2010-01-13 13 views
6

Tengo un problema donde tengo un modelo principal Foo, que tanto has_many :bars como has_many :bazes. Finalmente, también tengo un modelo de unión BarBaz que belongs_to :bar y belongs_to :baz. Quiero validar todos los bar_bazes para que su barra y baz pertenezcan al mismo foo. Pero parece que no puedo encontrar una manera de definir una fábrica para este modelo que sea válida.validaciones de asociación factory_girl

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 

me sale un error de registro válido cuando intento crear este último, debido a que el bar y baz factory_girl intenta asociar cada uno tiene su propio foo. ¿Estoy jodido?

Respuesta

5

Así que después de horas de darme un cabezazo al respecto, creo que finalmente tengo una solución. Aunque es bastante loco, espero que alguien más pueda mostrarme dónde estoy siendo estúpido.

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 

La cuestión clave es que es necesario que haya un foo en la base de datos ya se puede conseguir en las fábricas a través solos, ya que se puede utilizar variables locales o de código arbitrario en el rubí factories.rb (por lo que yo Puedo decir).

+0

este es un trabajo bastante impresionante. Buen trabajo – Trip

+0

Bueno, no puede ser tan bueno porque después de volver a él después de unos meses no recuerdo qué diablos estaba haciendo. :) – tfwright

0

La locura de crear fábricas con asociaciones profundamente anidadas me llevó a crear fixie que le permite crear registros de prueba utilizando ActiveRecord. Se ejecuta durante el paso db:test:prepare. Lo uso para eliminar la necesidad de accesorios. Puede continuar utilizando fábricas para objetos más fáciles de construir.

+0

Me gusta mucho, pero ¿por qué no podemos hacer que nuestra solución de fábrica permita el código arbitrario de Ruby en las definiciones de fábrica? – tfwright

+0

Puedes hasta cierto punto. El truco con el que debe trabajar es que las fábricas se llaman muchas veces y necesitan producir un objeto válido cada vez. Esto se complica con las asociaciones. –

Cuestiones relacionadas