ruby-on-rails - rails - factorybot gem
Poblando una asociación con niños en factory_girl (5)
FactoryGirl 4.3.0 está llamando a save!
en una asociación al invocar build
en el objeto principal, que creo que no pretende ser el comportamiento correcto.
Después de excavar el código de FactoryGirl, agregar strategy: :build
a la definición de asociación en la fábrica parece ahora crear mi asociación sin llamar a save!
.
Tengo un modelo Foo
que tiene_mucho ''Bar''. Tengo una factory_girl factory para cada uno de estos objetos. La fábrica de Bar tiene una asociación con Foo; creará una instancia de un Foo cuando cree la barra.
Me gustaría una fábrica que cree un Foo que contenga una barra. Idealmente, este Bar se crearía a través de: la fábrica de barras y respetaría la estrategia de compilación (crear / construir) utilizada para crear el Foo.
Sé que podría llamar a la fábrica de barras y luego tomar la referencia Foo del nuevo Bar. Me gustaría evitar esto; en mi caso de prueba, el objeto importante es Foo; llamar a la fábrica de Bar parece un poco tortuoso. Además, puedo ver la necesidad de un Foo con múltiples barras.
¿Es esto posible en factory_girl? ¿Cómo defines esta relación en el padre?
FactoryGirl ahora tiene una opción :method => :build
que puede usar en la asociación, que construirá el objeto asociado en lugar de crearlo.
Los Factory.after_ hooks
parecen ser la única forma de hacerlo con éxito. He descubierto una forma de mantener la estrategia de compilación sin duplicar el código:
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
La documentation indica que se llamará after_create
antes after_create
si se usa la estrategia :create
build. Si se utiliza :build
, solo se llama a after_build
y todo el mundo está contento.
También he creado una versión abstracta general aplicable en este momento para mantener las cosas SECAS.
Puede usar el método de association
ambas formas:
Factory.define :foo do |f|
# ...
f.association :bar
end
Si eso no funciona, puede asociarlos manualmente mediante una devolución de llamada. Aquí hay un ejemplo de una de mis aplicaciones:
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
Usando factory_girl-4.5.0
, crea n objetos secundarios en una fábrica de objetos padre
FactoryGirl.define do
factory :foo do
name "test"
after(:build) do |instance|
n.times { instance.bars << FactoryGirl.create(:bar) }
end
end
end