Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FactoryGirl: Populate a has many relation preserving build strategy

My problem seems very common, but I haven't found any answer in the documentation or the internet itself.

It might seem a clone of this question has_many while respecting build strategy in factory_girl but 2,5 years after that post factory_girl changed a lot.

I have a model with a has_many relation called photos. I want to populate this has many relation preserving my choice of build strategy.

If I call offering = FactoryGirl.build_stubbed :offering, :stay I expect offering.photos to be a collection of stubbed models.

The only way i've found to achieve this is this one:

factory :offering do
  association :partner, factory: :named_partner
  association :destination, factory: :geolocated_destination

  trait :stay do
    title "Hotel Gran Vía"
    description "Great hotel in a great zone with great views"
    offering_type 'stay'
    price 65
    rooms 70
    stars 4
    event_spaces 3
    photos do
      case @build_strategy
      when FactoryGirl::Strategy::Create then [FactoryGirl.create(:hotel_photo)]
      when FactoryGirl::Strategy::Build then [FactoryGirl.build(:hotel_photo)]
      when FactoryGirl::Strategy::Stub then [FactoryGirl.build_stubbed(:hotel_photo)]
      end
    end
  end
end

No need to say that IT MUST EXIST a better way of do that.

Ideas?

like image 403
miguel.camba Avatar asked Nov 09 '12 13:11

miguel.camba


2 Answers

Here's a slightly cleaner version of Flipstone's answer:

factory :offering do
  trait :stay do
    ...
    photos do
      association :hotel_photo, :strategy => @build_strategy.class
    end
  end
end
like image 125
Chewi Avatar answered Nov 17 '22 02:11

Chewi


You can use the various FactoryGirl callbacks:

factory :offering do
  association :partner, factory: :named_partner
  association :destination, factory: :geolocated_destination

  trait :stay do
    title "Hotel Gran Vía"
    description "Great hotel in a great zone with great views"
    offering_type 'stay'
    price 65
    rooms 70
    stars 4
    event_spaces 3
    after(:stub) do |offering|
      offering.photos = [build_stubbed(:hotel_photo)]
    end
    after(:build) do |offering|
      offering.photos = [build(:hotel_photo)]
    end
    after(:create) do |offering|
      offering.photos = [create(:hotel_photo)]
    end
  end
end
like image 10
Aaron Gibralter Avatar answered Nov 17 '22 01:11

Aaron Gibralter