在我的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
因此,如果我想创建一个新客户端,其前两个用户与之关联,我该怎么做?
e.g。
Client.create!(name: 'Client1', client_users: [User.first, User.second])
尝试这会给我一个错误:
ActiveRecord::AssociationTypeMismatch: ClientUser(#70142396623360) expected, got #<User id: 1,...
我也想为RSpec测试做这个。 e.g。
user1 = create(:user)
user2 = create(:user)
client1 = create(:client, client_users: [user1, user2])
如何在Rails控制台和RSpec测试中创建具有关联用户的客户端?
答案 0 :(得分:2)
如果你不想接受任何事情的accept_nested_attributes,那么你也可以将块传递给create。here。
Client.create!(name: 'Client1') do |client1|
client1.users << [User.find(1), User.find(2), User.find(3)]
end
答案 1 :(得分:1)
试试这个。它应该工作
Client.create!(name:'Client1')。client_users.new([{user_id: User.first},{user_id:User.second}])
答案 2 :(得分:1)
您可以使用以下代码执行此操作:
user1 = create(:user)
user2 = create(:user)
client1 = create(:client, users: [user1, user2])
有关文档
,请参阅ClassMethods/has_many集合=对象
通过删除和添加对象来替换集合内容 适当。如果:through选项是连接中的真回调 除了破坏回调之外,模型被触发,因为删除是 直接
如果您使用factory_girl,可以像这样添加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
答案 3 :(得分:0)
accepts_nested_attributes_for:users
并按原样行事:
Client.create!(name: 'Client1', users_attributes: { ........ })
希望这对你有用。
答案 4 :(得分: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