Ruby-on-rails Rails 3 跳过验证和回调
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7572652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails 3 skip validations and callbacks
提问by Johnny Klassy
I have a particularly complex model with validations and callbacks defined. The business needs now calls for a particular scenario where adding a new record requires skipping the validations and callbacks. What's the best way to do this?
我有一个特别复杂的模型,其中定义了验证和回调。业务现在需要一个特定场景,即添加新记录需要跳过验证和回调。做到这一点的最佳方法是什么?
回答by Dinatih
This works in Rails 3:
这适用于 Rails 3:
Model.skip_callback(:create)
model.save(:validate => false)
Model.set_callback(:create)
(API docsand related question)
回答by bowsersenior
Use ActiveRecord::Persistence#update_column, like this:
使用ActiveRecord::Persistence#update_column,像这样:
Model.update_column(field, value)
回答by Brad Werth
If the goal is to simply insert or update a record without callbacks or validations, and you would like to do it without resorting to additional gems, adding conditional checks, using RAW SQL, or futzing with your exiting code in any way, it may be possible to use a "shadow object" which points to your existing db table. Like so:
如果目标是在没有回调或验证的情况下简单地插入或更新记录,并且您希望在不求助于额外的 gem、添加条件检查、使用 RAW SQL 或以任何方式处理现有代码的情况下执行此操作,则可能是可以使用指向现有数据库表的“影子对象”。像这样:
class ImportedUser < ActiveRecord::Base
# To import users with no validations or callbacks
self.table_name = 'users'
end
This works with every version of Rails, is threadsafe, and completely eliminates all validations and callbacks with no modifications to your existing code. Just remember to use your new class to insert the object, like:
这适用于每个版本的 Rails,是线程安全的,并且完全消除了所有验证和回调,而无需修改现有代码。请记住使用您的新类插入对象,例如:
ImportedUser.new( person_attributes )
回答by Eric
I would recommend NOT using the skip_callback approach since it is not thread safe. The sneaky save gemhowever is since it just runs straight sql. Note this will not trigger validations so you will have to call them yourself (ex: my_model.valid?).
我建议不要使用 skip_callback 方法,因为它不是线程安全的。然而,偷偷摸摸的保存 gem是因为它只是直接运行 sql。请注意,这不会触发验证,因此您必须自己调用它们(例如:my_model.valid?)。
Here are some samples from their docs:
以下是他们文档中的一些示例:
# 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!
回答by Marcin Raczkowski
My take was like this (note: this disables callbacks on create, for update, delete and others you need to add them to array).
我的看法是这样的(注意:这会禁用创建、更新、删除和其他需要将它们添加到数组的回调)。
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
回答by Caley Woods
What about adding a method to your model that let's you skip the callbacks?
向您的模型添加一个方法,让您跳过回调怎么样?
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
If you end up using something like this, I would recommend using self in the method instead of the model name to avoid connascence of name.
如果你最终使用这样的东西,我建议在方法中使用 self 而不是模型名称,以避免名称的混淆。
I also ran across a gist from Sven Fuchs that looks nice, it's here
我还遇到了 Sven Fuchs 的一个看起来不错的要点,它在这里
回答by Nathan
I wrote a simple gem for skipping validations adhoc, but it could probably be updated to include skipping call backs as well.
我写了一个简单的 gem 来跳过临时验证,但它可能会更新以包括跳过回调。
https://github.com/npearson72/validation_skipper
https://github.com/npearson72/validation_skipper
You could take the can_skip_validation_forin the gem and add functionality for also skipping callbacks. Maybe call the method can_skip_validation_and_callbacks_for
您可以使用can_skip_validation_forgem 并添加功能以跳过回调。也许调用方法can_skip_validation_and_callbacks_for
Everything else would work the same. If you want help with doing that, let me know.
其他一切都一样。如果您在这方面需要帮助,请告诉我。
回答by TuteC
This hack worked for me at last (redefined _notify_comment_observer_for_after_createmethod for the object):
这个 hack 终于对我有用了(_notify_comment_observer_for_after_create为对象重新定义了方法):
if no_after_create_callback
def object._notify_comment_observer_for_after_create; nil; end
end
回答by Joshua Cook
None of these will work if your validations are written into the database itself.
如果您的验证被写入数据库本身,这些都将不起作用。
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------------------+--------------------------------------------------+------+-----+--------------------+----------------+
| status | enum('Big','Small','Ugly','Stupid','Apologetic') | NO | | Stupid | |

