2017-07-25 33 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這裏它不會自動分配。