Заполнение ассоциации с детьми в factory_girl - PullRequest
42 голосов
/ 30 мая 2010

У меня есть модель Foo, у которой есть 'Bar'. У меня есть фабрика factory_girl для каждого из этих объектов. Фабрика для Бара имеет ассоциацию с Foo; он будет создавать экземпляр Foo при создании бара.

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

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

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

Ответы [ 5 ]

50 голосов
/ 13 июня 2010

Кажется, что 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, и все довольны.

Я также создал абстрактную общеприменимую версию в этой сущности , чтобы сохранить вещи СУХИМ.

4 голосов
/ 30 мая 2010

Вы можете использовать метод 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
3 голосов
/ 29 декабря 2013

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

После просмотра кода FactoryGirl добавление strategy: :build к определению ассоциации на фабрике, похоже, создает мою ассоциацию без вызова save!.

3 голосов
/ 12 ноября 2011

FactoryGirl теперь имеет опцию :method => :build, которую вы можете использовать в ассоциации, которая будет создавать связанный объект, а не создавать его.

# 64: построение объекта создает ассоциации

2 голосов
/ 15 апреля 2015

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

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

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