Ruby-on-rails 如何在工厂女孩中创建 has_and_belongs_to_many 关联
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1484374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create has_and_belongs_to_many associations in Factory girl
提问by opsb
Given the following
鉴于以下
class User < ActiveRecord::Base
has_and_belongs_to_many :companies
end
class Company < ActiveRecord::Base
has_and_belongs_to_many :users
end
how do you define factories for companies and users including the bidirectional association? Here's my attempt
您如何为公司和用户定义工厂,包括双向关联?这是我的尝试
Factory.define :company do |f|
f.users{ |users| [users.association :company]}
end
Factory.define :user do |f|
f.companies{ |companies| [companies.association :user]}
end
now I try
现在我尝试
Factory :user
Perhaps unsurprisingly this results in an infinite loop as the factories recursively use each other to define themselves.
也许不出所料,这会导致无限循环,因为工厂递归地使用彼此来定义自己。
More surprisingly I haven't found a mention of how to do this anywhere, is there a pattern for defining the necessary factories or I am doing something fundamentally wrong?
更令人惊讶的是,我在任何地方都没有提到如何做到这一点,是否有定义必要工厂的模式,或者我在做一些根本错误的事情?
采纳答案by opsb
Factorygirl has since been updated and now includes callbacks to solve this problem. Take a look at http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girlfor more info.
Factorygirl 已经更新,现在包括回调来解决这个问题。查看http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl了解更多信息。
回答by Suborx
Here is the solution that works for me.
这是对我有用的解决方案。
FactoryGirl.define do
factory :company do
#company attributes
end
factory :user do
companies {[FactoryGirl.create(:company)]}
#user attributes
end
end
if you will need specific company you can use factory this way
如果您需要特定的公司,您可以这样使用工厂
company = FactoryGirl.create(:company, #{company attributes})
user = FactoryGirl.create(:user, :companies => [company])
Hope this will be helpful for somebody.
希望这对某人有帮助。
回答by Ashish
In my opinion, Just create two different factories like:
在我看来,只需创建两个不同的工厂,例如:
Factory.define :user, :class => User do |u| # Just normal attributes initialization end Factory.define :company, :class => Company do |u| # Just normal attributes initialization end
When you write the test-cases for user then just write like this
当你为用户编写测试用例时,就这样写
Factory(:user, :companies => [Factory(:company)])
Hope it will work.
希望它会起作用。
回答by auralbee
I couldn′t find an example for the above mentioned case on the provided website. (Only 1:N and polymorphic assocations, but no habtm). I had a similar case and my code looks like this:
我在提供的网站上找不到上述案例的示例。(只有 1:N 和多态关联,但没有 habtm)。我有一个类似的案例,我的代码如下所示:
Factory.define :user do |user|
user.name "Foo Bar"
user.after_create { |u| Factory(:company, :users => [u]) }
end
Factory.define :company do |c|
c.name "Acme"
end
回答by Larry Kooper
What worked for me was setting the association when using the factory. Using your example:
对我有用的是在使用工厂时设置关联。使用您的示例:
user = Factory(:user)
company = Factory(:company)
company.users << user
company.save!
回答by pasha.zhukov
Found this way nice and verbose:
发现这种方式既好又冗长:
FactoryGirl.define do
factory :foo do
name "Foo"
end
factory :bar do
name "Bar"
foos { |a| [a.association(:foo)] }
end
end
回答by Artur79
factory :company_with_users, parent: :company do
ignore do
users_count 20
end
after_create do |company, evaluator|
FactoryGirl.create_list(:user, evaluator.users_count, users: [user])
end
end
Warning:Change users: [user] to :users => [user] for ruby 1.8.x
警告:将用户:[user] 更改为 :users => [user] for ruby 1.8.x
回答by lucasarruda
For HABTM I used traits and callbacks.
对于 HABTM,我使用了 traits 和 callbacks。
Say you have the following models:
假设您有以下模型:
class Catalog < ApplicationRecord
has_and_belongs_to_many :courses
…
end
class Course < ApplicationRecord
…
end
You can define the Factory above:
您可以定义上面的工厂:
FactoryBot.define do
factory :catalog do
description "Catalog description"
…
trait :with_courses do
after :create do |catalog|
courses = FactoryBot.create_list :course, 2
catalog.courses << courses
catalog.save
end
end
end
end
回答by Nesha Zoric
Update for Rails 5:
Rails 5 的更新:
Instead of using has_and_belongs_to_manyassociation, you should consider: has_many :throughassociation.
而不是使用has_and_belongs_to_many关联,您应该考虑:has_many :through关联。
The user factory for this association looks like this:
此关联的用户工厂如下所示:
FactoryBot.define do
factory :user do
# user attributes
factory :user_with_companies do
transient do
companies_count 10 # default number
end
after(:create) do |user, evaluator|
create_list(:companies, evaluator.companies_count, user: user)
end
end
end
end
You can create the company factory in a similar way.
您可以以类似的方式创建公司工厂。
Once both factories are set, you can create user_with_companiesfactory with companies_count option. Here you can specify how many companies the user belongs to: create(:user_with_companies, companies_count: 15)
设置好两个工厂后,您可以user_with_companies使用companies_count option. 您可以在此处指定用户所属的公司数量:create(:user_with_companies, companies_count: 15)
You can find detailed explanation about factory girl associations here.
回答by Milan Novota
First of all I strongly encourage you to use has_many :through instead of habtm (more about this here), so you'll end up with something like:
首先,我强烈建议你使用 has_many :through 而不是 habtm(更多关于这个在这里),所以你最终会得到类似的东西:
Employment belongs_to :users
Employment belongs_to :companies
User has_many :employments
User has_many :companies, :through => :employments
Company has_many :employments
Company has_many :users, :through =>?:employments
After this you'll have has_many association on both sides and can assign to them in factory_girl in the way you did it.
在此之后,您将在双方都有 has_many 关联,并且可以按照您的方式在 factory_girl 中分配给它们。

