2010-01-13 4 views
6

У меня проблема, когда у меня есть родительская модель Foo, которая как has_many :bars, так и has_many :bazes. Наконец, у меня также есть модель объединения BarBaz, которая belongs_to :bar и belongs_to :baz. Я хочу проверить все bar_bazes так, чтобы его bar и bas принадлежали одному и тому же foo. Но я не могу понять, как определить фабрику для этой модели, которая была бы действительной.Validation

Factory.define(:bar) do |bar| 
    bar.association(:foo) 
end 

Factory.define(:baz) do |baz| 
    bar.association(:foo) 
end 

Factory.define(:bar_baz) do |bar_baz| 
    baz_bar.association(:foo) 
    baz_bar.association(:bar) 
    baz_bar.association(:baz) 
end 

Я получаю ошибку о неверном записи при попытке создать второй, так как бар и БАЗ factory_girl пытается связать это у каждого есть свои собственные Foo. Я привинчен?

ответ

5

Так что после нескольких часов избиения моей головы против этой проблемы, я думаю, что у меня наконец есть решение. Это очень сумасшествие, хотя, надеюсь, кто-то еще может показать мне, где я глуп.

Factory.define :foo do |foo| 
end 

Factory.define :bar do |bar| 
end 

Factory.define :baz do |baz| 
end 

Factory.define :foo_with_baz do |foo| 
    foo.after_create { |foo| Factory(:baz, :foo => foo) } 
end 

Factory.define :bar_baz do |bar_baz| 
    bar_baz.bar {|bar| bar.association(:bar, :foo => Factory(:foo_with_baz)) 
    bar_baz.after_build {| bar_baz| bar_baz.baz_id = bar_baz.foo.bars.first.id } 
end 

Ключевой вопрос в том, что там должна быть Foo в базе данных уже можно получить на заводы через один, так как вы можете использовать локальные переменные или произвольный код рубина в factories.rb (насколько я могу сказать).

+0

Это довольно впечатляющая работа. Отличная работа – Trip

+0

Ну, это не может быть так здорово, потому что, вернувшись к нему через несколько месяцев, я не могу вспомнить, какого черта я делал. :) – tfwright

0

Безумие создания заводов с глубоко вложенными ассоциациями привело меня к созданию fixie, что позволяет создавать тестовые записи с использованием ActiveRecord. Он работает во время этапа db:test:prepare. Я использую его для устранения необходимости в светильниках. Вы можете продолжать использовать фабрики для упрощаемых объектов.

+0

Мне это очень нравится, но почему мы не можем заставить наше заводское решение разрешить произвольный код Ruby в определениях Factory? – tfwright

+0

Вы можете в некоторой степени. Трюк, который вам нужно обойти, заключается в том, что фабрики называются много раз и каждый раз нужно создавать действительный объект. Это становится беспорядочным с ассоциациями. –