Подтвердить что ты не робот

Наведение ассоциации с детьми в factory_girl

У меня есть модель Foo, которая has_many 'Bar'. У меня есть factory_girl factory для каждого из этих объектов. factory for Bar имеет связь с Foo; он будет создавать экземпляр Foo, когда он создает панель.

Мне нужен factory, который создает Foo, содержащий панель. В идеале этот бар будет создан через: bar factory и будет уважать стратегию сборки (создание/сборку), используемую для создания Foo.

Я знаю, что могу просто позвонить: bar factory, а затем захватить ссылку Foo из новой панели. Я бы хотел этого избежать; в моем тестовом примере важным объектом является Foo; вызов бар factory кажется немного обходным. Кроме того, я вижу необходимость в Foo с несколькими барами.

Возможно ли это в factory_girl? Как вы определяете эту взаимосвязь в родительском?

4b9b3361

Ответ 1

Factory.after_ hooks представляется единственным способом сделать это успешно. Я понял способ сохранить стратегию сборки без дублирования кода:

Factory.define :foo do |f|
  f.name "A Foo"
  f.after(:build) { |foo|
    foo.bars << Factory.build(:bar, :foo => foo)
  }
  f.after(:create) { |foo|
    foo.bars.each { |bar| bar.save! }
  }
end

В документации указано, что after_build будет вызываться до after_create, если используется стратегия построения :create. Если используется :build, тогда вызывается только after_build, и все довольны.

Я также создал абстрактную общепринятую версию в этом контексте, чтобы сохранить вещи DRY.

Ответ 2

Вы можете использовать метод association в обоих направлениях:

Factory.define :foo do |f|
  # ...
  f.association :bar
end

Если это не сработает, вы можете связать их вручную, используя обратный вызов. Вот пример из одного из моих приложений:

Factory.define :live_raid do |raid|
end

Factory.define :live_raid_with_attendee, :parent => :live_raid do |raid|
  raid.after_create { |r| Factory(:live_attendee, :live_raid => r) }
end

Ответ 4

FactoryGirl 4.3.0 вызывает save! в ассоциации при вызове build на родительском объекте, который, я считаю, не предназначен для правильного поведения.

После копания кода FactoryGirl добавление strategy: :build в определение ассоциации в factory кажется теперь созданием моей ассоциации без вызова save!.

Ответ 5

Используя factory_girl-4.5.0, создайте n дочерних объектов в родительском объекте factory

FactoryGirl.define do
  factory :foo do
    name "test"        

    after(:build) do |instance|
      n.times { instance.bars << FactoryGirl.create(:bar) }          
    end
  end
end