2017-09-27 94 views
1

在我的Rails應用程序中,我擁有客戶端和用戶。用戶可以擁有多個客戶端。在Rails中創建具有關聯的對象

的模型設置爲這樣:

class Client < ApplicationRecord 
    has_many :client_users, dependent: :destroy 
    has_many :users, through: :client_users 
end 

class User < ApplicationRecord 
    has_many :client_users, dependent: :destroy 
    has_many :clients, through: :client_users 
end 

class ClientUser < ApplicationRecord 
    belongs_to :user 
    belongs_to :client 
end 

所以,如果我想創造一個新的客戶端,有我會怎麼做與之相關聯的前兩個用戶?

例如

Client.create!(name: 'Client1', client_users: [User.first, User.second]) 

嘗試,讓我的錯誤:

ActiveRecord::AssociationTypeMismatch: ClientUser(#70142396623360) expected, got #<User id: 1,... 

我也想爲一個RSpec測試做到這一點。例如

user1 = create(:user) 
user2 = create(:user) 

client1 = create(:client, client_users: [user1, user2]) 

如何在Rails控制檯和RSpec測試中爲關聯用戶創建客戶端?

+0

嘗試這個 'User.create(名稱: 'oneuser') User.create(名稱: 'twouser') @client = Client.create(名稱: '客戶端1') @ client.users << User.first @ client.users << User.second' –

+0

@VaibhavDhoke所以客戶端必須先存在?我無法同時創建和關聯? – Cameron

+0

這是做到這一點的一種方式,也許這也可以完成,但我不知道它。仍然。請參閱此鏈接(http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association)以獲取更多信息。 –

回答

0

accepts_nested_attributes_for :users

,做像這樣:

Client.create!(name: 'Client1', users_attributes: { ........ })

希望這會爲你工作。

2

如果您不想爲任何東西accept_nested_attributes,如記錄here您也可以傳遞塊來創建。

Client.create!(name: 'Client1') do |client1| 
    client1.users << [User.find(1), User.find(2), User.find(3)]  
end 
1

試試這個。它應該工作

Client.create!(name: 'Client1').client_users.new([{user_id: User.first},{user_id: User.second}])

+0

@Cameron嘗試以上解決方案 – krishnar

0

你可以利用回調的after_create

class Client < ApplicationRecord 
    has_many :client_users, dependent: :destroy 
    has_many :users, through: :client_users 

    after_create :add_users 

    private def add_users 
    sef.users << [User.first, User.second] 
    end 
end 

另外,一個更簡單的方法是

Client.create!(name: 'Client1', user_ids: [User.first.id, User.second.id]) 
1

您可以用下面的代碼做到這一點:

user1 = create(:user) 
user2 = create(:user) 

client1 = create(:client, users: [user1, user2]) 

如果您正在使用factory_girl的文檔

collection=objects

Replaces the collections content by deleting and adding objects as appropriate. If the :through option is true callbacks in the join models are triggered except destroy callbacks, since deletion is direct.

ClassMethods/has_many您可以添加trait :with_users這樣的:

FactoryGirl.define do 
    factory :client do 

    trait :with_two_users do 
     after(:create) do |client| 
     client.users = create_list :user, 2 
     end 
    end 

    end 
end 

現在你可以在測試創建與用戶客戶端這樣的:

client = create :client, :with_two_users 
0

你得到不匹配的原因是因爲你指定client_users協會期望ClientUser種情況下,但你傳遞User實例:

# this won't work 
Client.create!(client_users: [User.first, User.second]) 

相反,因爲你已經指定了users的關聯,你可以這樣做:

Client.create!(users: [User.first, User.second]) 

還有一個更簡單的處理這種方式,雖然:溝渠連接模型並使用has_and_belongs_to_many關係。數據庫中仍然需要一個clients_users連接表,但不需要ClientUser模型。 Rails將在封面下自動處理。

class Client < ApplicationRecord 
    has_and_belongs_to_many :users 
end 

class User 
    has_and_belongs_to_many :clients 
end 

# Any of these work: 
client = Client.new(name: "Kung Fu") 
user = client.users.new(name: "Panda") 
client.users << User.new(name: "Nemo") 
client.save # => this will create two users and a client, and add two records to the `clients_users` join table 
相關問題