我有一个特别复杂的模型,其中定义了验证和回调。业务需求现在需要一个特定的场景,添加新记录需要跳过验证和回调。最好的方法是什么?
答案 0 :(得分:118)
这适用于Rails 3:
Model.skip_callback(:create)
model.save(:validate => false)
Model.set_callback(:create)
答案 1 :(得分:29)
使用ActiveRecord::Persistence#update_column,如下所示:
Model.update_column(field, value)
答案 2 :(得分:10)
如果目标是简单地插入或更新没有回调或验证的记录,并且您希望在不借助其他宝石,添加条件检查,使用RAW SQL或以任何方式使用现有代码的情况下执行此操作,可以使用指向现有数据库表的“影子对象”。像这样:
class ImportedUser < ActiveRecord::Base
# To import users with no validations or callbacks
self.table_name = 'users'
end
这适用于每个版本的Rails,是线程安全的,并且完全消除了所有验证和回调,而无需修改现有代码。只需记住使用新类插入对象,例如:
ImportedUser.new( person_attributes )
答案 3 :(得分:2)
我的观点是这样的(注意:这会禁用创建,更新,删除以及其他需要将它们添加到数组的回调)。
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
答案 4 :(得分:1)
如何向模型中添加一个方法,让您跳过回调?
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
如果你最终使用这样的东西,我建议在方法中使用self而不是模型名称,以避免名称的出现。
我还遇到了Sven Fuchs的一个好看,看起来不错,here
答案 5 :(得分:1)
我写了一个简单的宝石来跳过验证adhoc,但它可能会更新以包括跳过回调。
https://github.com/npearson72/validation_skipper
您可以在gem中使用can_skip_validation_for
并添加用于跳过回调的功能。也许调用方法can_skip_validation_and_callbacks_for
其他一切都会起作用。如果您需要帮助,请告诉我。
答案 6 :(得分:1)
我建议不要使用skip_callback方法,因为它不是线程安全的。然而sneaky save gem因为它只是直接运行sql。请注意,这不会触发验证,因此您必须自己调用它们(例如: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!
答案 7 :(得分:0)
这个hack终于为我工作了(重新定义了对象的_notify_comment_observer_for_after_create
方法):
if no_after_create_callback
def object._notify_comment_observer_for_after_create; nil; end
end
答案 8 :(得分:0)
如果您的验证被写入数据库本身,这些都不会起作用。
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| status | enum('Big','Small','Ugly','Stupid','Apologetic') | NO | | Stupid | |