2017-07-25 32 views
1

使用Rails 5,我有一个问题,当我尝试保存我的这2款机型之间的关联之间保存:用户和提供商协不2款

我的模型:

class User < ApplicationRecord 
    # Relations 
    has_and_belongs_to_many :providers 
end 


class Provider < ApplicationRecord 
    # Relations 
    has_and_belongs_to_many :users 
    accepts_nested_attributes_for :users 
end 

控制器:

class ProvidersController < ApplicationController 
    def new 
    @provider = current_user.providers.new 
    end 

    def create 
    @provider = current_user.providers.new(provider_params) 
    if @provider.save 
     redirect_to root_path 
    else 
     render :new 
    end 
    end 

    private 

    def provider_params 
     params[:provider][:status] = 'name' 
     params.require(:provider).permit(:name, :status) 
    end 

形式:

= simple_form_for @provider do |f| 
    = f.error_notification 
    = f.input :name, required: false 
    = f.button :submit 

在创建操作上,创建了一个新提供者,但它没有链接到当前用户。 (在连接表中没有数据)

我不知道为什么我有这种行为。 在控制台,如果我这样做:

@user = User.create(email: "[email protected]", password: "password") 
@provider = @user.providers.create(name: "Provider1", status: "name") 
@provider.save 

则关联正确保存。

> @user.providers 
=> #<ActiveRecord::Associations::CollectionProxy [#<Provider id: 17, name: "Provider1", status: "name", created_at: "2017-07-25 09:37:19", updated_at: "2017-07-25 09:37:19">]> 

感谢您的任何想法!

有关信息,我的架构:

create_table "providers", force: :cascade do |t| 
    t.string "name" 
    t.string "status" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

create_table "providers_users", id: false, force: :cascade do |t| 
    t.bigint "provider_id", null: false 
    t.bigint "user_id", null: false 
    t.index ["provider_id", "user_id"], name: "index_providers_users_on_provider_id_and_user_id" 
    t.index ["user_id", "provider_id"], name: "index_providers_users_on_user_id_and_provider_id" 
end 

create_table "users", force: :cascade do |t| 
    t.string "email", default: "", null: false 
    t.string "encrypted_password", default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count", default: 0, null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.inet "current_sign_in_ip" 
    t.inet "last_sign_in_ip" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.index ["email"], name: "index_users_on_email", unique: true 
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 
end 

这里是日志

ÈStarted POST "/providers" for 127.0.0.1 at 2017-07-25 11:49:27 +0200 
    Processing by ProvidersController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"27O2Tz4bbqhfRmcuq+0DIZMebSaYVc6IO/uy889Z48fF1l3c8GfIZ+WcQvZKfUeEIB5+YbrM9dON2RH47p3TIQ==", "provider"=>{"name"=>"My new provider"}, "commit"=>"Sauvegarder"} 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 5], ["LIMIT", 1]] 
    (0.2ms) BEGIN 
    SQL (0.4ms) INSERT INTO "providers" ("name", "status", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "My new provider"], ["status", "name"], ["created_at", "2017-07-25 09:49:27.837165"], ["updated_at", "2017-07-25 09:49:27.837165"]] 
    (4.0ms) COMMIT 
    Redirected to http://localhost:3000/providers/18/steps.location 
    Completed 302 Found in 12ms (ActiveRecord: 5.0ms) 


    Started GET "/providers/18/steps.location" for 127.0.0.1 at 2017-07-25 11:49:27 +0200 
    Processing by Providers::StepsController#index as 
    Parameters: {"provider_id"=>"18"} 
    Redirected to http://localhost:3000/providers/18/steps/registration 
    Completed 302 Found in 2ms (ActiveRecord: 0.0ms) 


    Started GET "/providers/18/steps/registration" for 127.0.0.1 at 2017-07-25 11:49:27 +0200 
    Processing by Providers::StepsController#show as HTML 
    Parameters: {"provider_id"=>"18", "id"=>"registration"} 
    Provider Load (0.3ms) SELECT "providers".* FROM "providers" WHERE "providers"."id" = $1 LIMIT $2 [["id", 18], ["LIMIT", 1]] 
    Rendering providers/steps/registration.html.haml within layouts/provider 
    User Load (0.3ms) SELECT "users".* FROM "users" INNER JOIN "providers_users" ON "users"."id" = "providers_users"."user_id" WHERE "providers_users"."provider_id" = $1 [["provider_id", 18]] 
    Rendered providers/steps/registration.html.haml within layouts/provider (13.2ms) 
    Rendered shared/_head.html.haml (30.6ms) [cache miss] 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 5], ["LIMIT", 1]] 
    Rendered shared/_header.html.haml (9.7ms) [cache miss] 
    Completed 200 OK in 69ms (Views: 64.7ms | ActiveRecord: 1.1ms) 
+0

向我们展示在提交被触发时生成的日志。 – Pavan

+0

@Pavan请显示我的日志,重定向有点不同。谢谢 ! – benoitr

+0

等一下!根据您的表格和控制器,您只能向提供商发送输入信息! – Pavan

回答

1

我也许知道这是不是最好的解决方案,但它是在我脑海

最快
def create 
    @provider = current_user.providers.create(provider_params) 
    if @provider.id 
     redirect_to root_path 
    else 
     render :new 
    end 
    end 

这将创建连接表记录,当你使用新的唯一的原因,如果属于的话,如果提供者属于给用户并且在迁移时拥有user_id current_user.providers.new会在新实例中添加user_id,万一有,并且属于许多你可以这样做,也许有更好的办法,但这是我首先想到的。

或像这样

def create 
    @provider = Provider.new(provider_params) 
    if @provider.save 
     current_user.providers << @provider 
     redirect_to root_path 
    else 
     render :new 
    end 
    end 

多了一个线,但我想看起来更干净。

+0

你想说什么? – Pavan

+0

我在我的项目上尝试了这个解决方案,并且得到了OP期望它在一行提供程序中创建的结果,并且还加入了表记录提供程序和用户。 –

+0

这个解决方案有效,Sedad :)在我看来这有点奇怪。如果有更好的解决方案,我会等一会儿。非常感谢 ! – benoitr

1
def create 
    @provider = current_user.providers.new(provider_params) 
    @provider.users = [current_user] 
    if @provider.save 
    redirect_to root_path 
    else 
    render :new 
    end 
end 

我建议使用has_many through关系,而不是has_many_and_belongs_to,因为你可以查询连接表,并有可能在此连接表中添加未来的某个更多的列,如有需要。

P.S.这感觉就像我的Rails bug /功能改进。 @provider.users = [current_user]不再需要,因为@provider = current_user.providers.new(provider_params)已经可以推断出@provider对象已经与current_user相关联,因此应该已经自动分配了。但这已经与has_many一起工作。似乎只有在HABTM这里它不会自动分配。