我正在试图弄清楚如何编写属于2个不同模型的工厂,每个模型应该具有相同的父模型。这是设计的示例代码:
class User < ActiveRecord::Base
has_many :widgets
has_many :suppliers
attr_accessible :username
end
class Widget < ActiveRecord::Base
belongs_to :user
has_many :parts
attr_accessible :name
end
class Supplier < ActiveRecord::Base
belongs_to :user
has_many :parts
attr_accessible :name
end
class Part < ActiveRecord::Base
belongs_to :supplier
belongs_to :widget
attr_accessible :name
end
这是我到目前为止所拥有的:
factory :user do
name 'foo'
end
factory :widget do
association :user
name 'widget'
end
factory :supplier do
association :user
name 'supplier'
end
factory :part do
association :widget
association :supplier
name 'part'
end
问题在于part.widget.user != part.supplier.user
并且它们必须相同。
我尝试过以下方法但没有成功:
factory :part do
association :widget
association :supplier, user: widget.user
name 'part'
end
有什么建议吗?或者在创建零件后我是否需要修改它?
谢谢
答案 0 :(得分:8)
我相信你可以用callback:
来做到这一点factory :part do
association :widget
association :supplier
name 'part'
after(:create) do |part|
user = FactoryGirl.create(:user)
part.widget.user = part.supplier.user = user
end
end
另请参阅:Get two associations within a Factory to share another association
答案 1 :(得分:0)
另一种选择是使用瞬态变量来传递相关对象。
我通常使用两个变量:
它的外观如下:
factory :part do
transient do
# this variable is so we can specify the user
with_user { no_user ? nil : Factory.create(:user) }
# this variable allows the user to be nil
no_user false
end
# The transient variable for_user can now be used to create the
# associations for this factory
widget { Factory.create(:widget, :user => with_user) }
supplier { Factory.create(:supplier, :user => with_user) }
name 'part'
end
然后可以通过以下方式使用它:
# use the default user
part = Factory.create :part
part.widget.user.should == part.supplier.user
# use a custom created user
user = Factory.create :user, :name => 'Custom user'
part = Factory.create :part, for_user: user
part.widget.user.should == user
part.supplier.user.should == user
# create a part without any user
# (again this probably isn't need in your specific case, but I have
# found it a useful pattern)
part = Factory.create :part, no_user: true
part.widget.user.should be_nil
part.supplier.user.should be_nil