6

我试图弄清楚如何编写一个属于 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

有什么建议么?还是我必须在创建零件后对其进行修改?

谢谢

4

2 回答 2

8

我相信你可以通过回调来做到这一点:

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

另请参阅:在工厂中获取两个关联以共享另一个关联

于 2012-10-24T02:30:46.880 回答
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
于 2016-02-07T23:11:11.900 回答