Rails 3跳过验证和回调

时间:2011-09-27 16:40:01

标签: ruby-on-rails ruby-on-rails-3 activerecord

我有一个特别复杂的模型,其中定义了验证和回调。业务需求现在需要一个特定的场景,添加新记录需要跳过验证和回调。最好的方法是什么?

9 个答案:

答案 0 :(得分:118)

这适用于Rails 3:

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

API docsrelated question

答案 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             |                |
相关问题