vista validaciones una relaciones rails parciales nueva formulario crear controladores ruby-on-rails ruby-on-rails-3 activerecord

ruby-on-rails - validaciones - ruby on rails crear formulario



Rails 3 validaciones de salto y devoluciones de llamadas (9)

Tengo un modelo particularmente complejo con validaciones y devoluciones de llamadas definidas. Las necesidades del negocio ahora requieren un escenario particular donde agregar un nuevo registro requiere omitir las validaciones y devoluciones de llamadas. ¿Cuál es la mejor manera de hacer esto?


¿Qué hay de agregar un método a su modelo que le permite omitir las devoluciones de llamada?

class Foo < ActiveRecord::Base after_save :do_stuff def super_secret_create(attrs) self.skip_callback(:create) self.update_attributes(attrs) self.save(:validate => false) self.set_callback(:create) end end

Si terminas usando algo como esto, te recomendaría usar self en el método en lugar del nombre del modelo para evitar la connivencia del nombre.

También encontré una idea de Sven Fuchs que se ve bien, está here


Escribí una gema simple para saltear las validaciones adhoc, pero probablemente podría actualizarse para incluir saltarse las llamadas.

https://github.com/npearson72/validation_skipper

Puede tomar can_skip_validation_for en la gema y agregar funcionalidad para también omitir devoluciones de llamada. Tal vez llame al método can_skip_validation_and_callbacks_for

Todo lo demás funcionaría igual. Si quieres ayuda para hacerlo, avísame.


Este truco me funcionó por fin (método _notify_comment_observer_for_after_create redefinido para el objeto):

if no_after_create_callback def object._notify_comment_observer_for_after_create; nil; end end


Esto funciona en Rails 3:

Model.skip_callback(:create) model.save(:validate => false) Model.set_callback(:create)

( API docs y preguntas relacionadas )


Mi opinión fue así (nota: esto desactiva las devoluciones de llamada en crear, actualizar, eliminar y otras que necesita para agregarlas a la matriz).

begin [:create, :save].each{|a| self.class.skip_callback(a) } # We disable callbacks on save and create # create new record here without callbacks, tou can also disable validations with # .save(:validate => false) ensure [:create, :save].each{|a| self.class.set_callback(a) } # and we ensure that callbacks are restored end


Ninguno de estos funcionará si sus validaciones están escritas en la base de datos.

+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+ | status | enum(''Big'',''Small'',''Ugly'',''Stupid'',''Apologetic'') | NO | | Stupid | |


Si el objetivo es simplemente insertar o actualizar un registro sin devoluciones de llamada o validaciones, y le gustaría hacerlo sin recurrir a gemas adicionales, agregar comprobaciones condicionales, usar SQL RAW o actualizar su código de salida de alguna manera, puede ser es posible utilizar un "objeto sombra" que apunta a su tabla db existente. Al igual que:

class ImportedUser < ActiveRecord::Base # To import users with no validations or callbacks self.table_name = ''users'' end

Esto funciona con todas las versiones de Rails, es seguro para los hilos y elimina por completo todas las validaciones y devoluciones de llamadas sin modificaciones a su código existente. Solo recuerde usar su nueva clase para insertar el objeto, como:

ImportedUser.new( person_attributes )



Yo recomendaría NO usar el enfoque skip_callback ya que no es seguro para subprocesos. Sin embargo, la gema astuta de guardar es que simplemente se ejecuta directamente en sql. Tenga en cuenta que esto no activará las validaciones, por lo que tendrá que llamarlas usted mismo (por ejemplo: my_model.valid?).

Aquí hay algunas muestras de sus documentos:

# Update. Returns true on success, false otherwise. existing_record.sneaky_save # Insert. Returns true on success, false otherwise. Model.new.sneaky_save # Raise exception on failure. record.sneaky_save!