我有一个用例,我想根据所包含的特征来操作工厂中的 transient 属性。有没有办法做到这一点,或者有更好的方法来完成我想要完成的任务?
假设我正在构建一个 House
目的。 house
可以有很多windows
。我想创建一些子工厂来自动创建一些窗口,但我希望能够为特定类型的窗口添加特征。 window_types
transient 属性实际上是 window
的特征列表工厂。
factory :house do
floors 3
exterior 'Brick'
transient do
window_types { [:bay, :double_hung] }
end
trait :with_picture_window do
window_types.push(:picture)
end
factory :ranch_house do
floors 1
after(:create) do |house, evaluator|
evaluator.window_types.each do |window_type|
FactoryGirl.create :window, window_type
end
end
end
factory :mountain_house do
floors 2
exterior 'Log'
after(:create) do |house, evaluator|
evaluator.window_types.each do |window_type|
FactoryGirl.create :window, window_type
end
end
end
end
factory :window do
material 'Glass'
trait :bay do
# bay window attributes
end
trait :double_hung do
# double hung window attributes
end
trait :picture do
# picture window attributes
end
end
这会抛出 NoMethodError: undefined method 'push' for #<FactoryGirl::Declaration::Implicit>
:with_picture_window
内的错误特征。
为了便于讨论,假设我确实需要不同的工厂来 build 这些房子。有没有办法可以从特征中修改 window_types transient 属性,然后让该 transient 属性反射(reflect)在我的子工厂中?
我希望能够做到:
FactoryGirl.create :ranch_house
# creates a ranch house with only bay and double_hung windows
FactoryGirl.create :ranch_house, :with_picture_window
# creates a ranch house with bay, double_hung, AND picture windows
如果没有,是否有更好的方法可以实现这一目标?
提前非常感谢。
最佳答案
根据 Ben 提出的想法,我找到了合适的解决方案。我使用本地数组变量来存储需要创建的窗口的类型。每个窗口的特征将窗口类型添加到 after(:build)
block 中的数组中。然后,在 after(:create)
block 中,我实际创建了窗口记录。
第一个 after(:build)
block (不在 trait
中的 block )很重要,因为它会重置 window_types
数组对象创建。
FactoryGirl.define do
window_types = []
factory :house do
floors 3
exterior 'Brick'
after(:build) do
window_types = []
end
after(:create) do |house|
window_types.each do |window_type|
FactoryGirl.create(:window, window_type, house: house)
end
end
trait :with_picture_window do
after(:build) do
window_types << :picture
end
end
trait :with_double_hung_window do
after(:build) do
window_types << :double_hung
end
end
trait :with_bay_window do
after(:build) do
window_types << :bay
end
end
factory :house_with_bay_and_picture_window, traits: [:bay, :picture]
end
end
我很好奇听到关于这种方法的任何想法。目前来说,这符合我的需求,而且非常灵活。
关于ruby-on-rails - 工厂女孩 - 操纵 transient 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36463468/