ruby-on-rails - sheet - factory bot rails tutorial
Omita las validaciones de Rails al crear objetos FactoryGirl (4)
¿Qué tal esto?
FactoryGirl.build(:model_a).save(validate: false)
EDITAR: Como Scott McMillin comenta a continuación, si desea que el objeto creado sea una variable, puede hacer esto:
model_a = FactoryGirl.build(:model_a)
model_a.save(validate: false)
Tengo dos modelos (ModelA y ModelB), y fábricas FactoryGirl para cada uno. Quiero que la fábrica para ModelB pueda (A) crear datos de prueba y (B) construir (sin guardar en la base de datos) datos de muestra para mostrarlos a los clientes. Estoy teniendo problemas para que (A) funcione debido a las validaciones de Rails en mis modelos.
Modelo A:
class ModelA < ActiveRecord::Base
belongs_to :model_b
validates_presence_of :model_b
end
Fábrica para ModelA:
FactoryGirl.define do
factory :model_a do
some_attr "hello"
model_b { FactoryGirl.build :model_b }
end
end
Modelo B
class ModelB < ActiveRecord::Base
has_one :model_a
end
Fábrica para ModelB
FactoryGirl.define do
factory :model_b do
some_attr "goodbye"
end
end
No puedo crear objetos de estas fábricas sin obtener errores de validación:
ruby> FactoryGirl.create :model_a
ActiveRecord::RecordInvalid: Validation failed: ModelB can''t be blank
Parece que FactoryGirl está intentando guardar el objeto de fábrica antes de guardar sus asociaciones. Me doy cuenta de que podría hacer que la fábrica para ModelB cree su ModelA asociado (en lugar de compilarlo); sin embargo, perdería la flexibilidad de poder usar la fábrica ModelA para generar datos de muestra o guardar datos de prueba. Alternativamente, podría quitar las validaciones; Pero entonces no tendría validaciones.
¿Alguna otra opción?
Busqué en un par de soluciones.
Una es crear un proxy personalizado, ilustrado aquí: http://codetunes.com/2009/11/05/fixtures-without-validation-with-factory-girl
La otra es establecer un bloque to_create
en la fábrica:
FactoryGirl.define do
factory :model_a do
model_b { FactoryGirl.build :model_b }
to_create do |instance|
instance.model_b.save!
instance.save!
end
end
end
Esta validación circular no es una buena idea. ¿Cómo pretende construir objetos reales en la base de datos? Imho eso es simplemente imposible.
Primero debe guardar objetos en la base de datos, la identificación la asigna la ID y solo después de crear / guardar el objeto puede referirse al objeto utilizando la ID en una clave externa. Entonces, para poder referirse a un registro en la base de datos, primero se debe guardar. Pero si las validaciones requieren que las ID sean conocidas y estén presentes antes de guardar ...
En una relación de relación de belongs_to
, la clave externa está en la tabla, y luego puede expresar la necesidad de que la clave esté presente. Con la relación has_one
, la clave foránea está en la otra tabla y no puede expresar la validación de que el elemento debería estar presente. Así que debes eliminar la validación de ModelB
.
Espero que esto ayude.
[ACTUALIZAR]
¿Intentaste escribir:
FactoryGirl.define do
factory :model_a do
some_attr "hello"
model_b
end
end
También encontré el mismo problema, que el modelo no se puede guardar cuando las asociaciones no se pudieron guardar.
Quizás intente esto: https://github.com/thoughtbot/factory_girl/issues/369 ?