Rails 3跳过validation和callback

我有一个特别复杂的模型,包含validation和callback定义。 业务需求现在需要添加新logging的特定场景需要跳过validation和callback。 什么是最好的方法来做到这一点?

这在Rails 3中工作:

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

( API文档和相关问题 )

使用ActiveRecord :: Persistence#update_column ,像这样:

 Model.update_column(field, value) 

如果目标是简单地插入或更新没有callback或validation的logging,并且您希望在不诉诸附加gem的情况下执行该操作,添加条件检查,使用RAW SQL或以任何方式使用退出代码,可能使用指向您现有的数据库表的“阴影对象”。 像这样:

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

这适用于Rails的每个版本,是线程安全的,并且完全消除所有的validation和callback,而不需要修改现有的代码。 只要记住使用你的新类插入对象,如:

 ImportedUser.new( person_attributes ) 

我的是这样的(注意:这将禁用创build,更新,删除和其他人你需要将其添加到数组的callback)。

  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 

如何在您的模型中添加一个方法让您跳过callback?

 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 

如果你最终使用这样的东西,我会build议在方法中使用自己而不是模型名称,以避免名称的变种。

我也从Sven Fuchs那里跑过来,看起来不错,就在这里

我写了一个简单的gem跳过validationadhoc,但它可能会更新,以包括跳过callback以及。

https://github.com/npearson72/validation_skipper

您可以在gem中使用can_skip_validation_for ,并添加跳过callback的function。 也许调用方法can_skip_validation_and_callbacks_for

其他一切工作都是一样的。 如果你需要帮助,请告诉我。

我build议不要使用skip_callback方法,因为它不是线程安全的。 然而, 偷偷摸摸的保存gem ,因为它只是直接运行sql。 请注意,这不会触发validation,因此您必须自己调用它们(例如:my_model.valid?)。

以下是他们的文档中的一些示例:

 # 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! 

这个黑客终于为我工作了(为对象重新定义了_notify_comment_observer_for_after_create方法):

 if no_after_create_callback def object._notify_comment_observer_for_after_create; nil; end end 

如果您的validation写入数据库本身,这些都不会起作用。

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