0

I have a factory and a trait. I'd want to set attribute in factory and later modify this attribute using 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

As you see it raises SystemStackError. How can I set value of photos attribute in a trait based on value that was set for this attribute in factory?

4

3 回答 3

0

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

trait :non_broken do
  # build non_broken photos only
end
于 2013-07-02T11:36:37.583 回答
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
于 2013-07-02T11:49:54.093 回答
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
于 2013-07-02T12:22:17.497 回答