如何根据FactoryGirl中此属性的先前值设置属性?

时间:2013-07-02 10:54:55

标签: ruby factory-bot

我有工厂和特质。我想在工厂设置属性,然后使用trait修改此属性:

factory :photo_gallery do
  photos { PhotosGenerator.generate_10_photos }

  after(:build) do |photo_gallery|
    # set value of some other attribute based on value of photos attribute
  end
end

trait :non_broken do
  photos { photos.reject(&:broken?) } # raises `stack level too deep (SystemStackError)`
end

如你所见,它会引发SystemStackError。如何根据在工厂中为此属性设置的值在特征中设置photos属性的值?

3 个答案:

答案 0 :(得分:0)

我认为你不应该在特征中“过滤”你的照片集。相反,你应该“建立”你所需要的东西。

trait :non_broken do
  # build non_broken photos only
end

答案 1 :(得分:0)

这一行是递归的:

photos { photos.reject(&:broken?) }

特质不像遗产;您无法调用“超级”实现,而是最后应用的特征将是唯一使用的实现。

您需要完全重新定义photos属性,而不需要参考之前的实现,如下所示:

photos { PhotosGenerator.generate_10_photos(broken: false) }

或者,您可以使用回调,这样您就不会重新定义属性,而是在设置后更改它:

trait :non_broken do
  after :build do |object|
    object.photos.reject!(&:broken?)
  end
end

答案 2 :(得分:0)

将额外的忽略属性添加到工厂并使用它来访问特征中的照片:

factory :photo_gallery do
  ignore do
    temp_photos { PhotosGenerator.generate_10_photos }
  end

  photos { temp_photos }
end

trait :non_broken do
  photos { temp_photos.reject(&:broken?) } # OK
end