Ruby-on-rails 如何在不执行“before_save”的情况下“update_attributes”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7243729/
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
How to "update_attributes" without executing "before_save"?
提问by Misha Moroshko
I have a before_savein my Messagemodel defined like this:
before_save我的Message模型中有一个这样定义的:
class Message < ActiveRecord::Base
before_save lambda { foo(publisher); bar }
end
When I do:
当我做:
my_message.update_attributes(:created_at => ...)
fooand barare executed.
foo并被bar处决。
Sometimes, I would like to update message's fields without executing fooand bar.
有时,我想在不执行foo和的情况下更新消息的字段bar。
How could I update, for example, the created_atfield (in the database) without executing fooand bar?
例如,如何created_at在不执行fooand 的情况下更新字段(在数据库中)bar?
回答by jbescoyez
In rails 3.1 you will use update_column.
在 rails 3.1 中,您将使用update_column。
Otherwise:
除此以外:
In general way, the most elegant way to bypass callbacks is the following:
一般来说,绕过回调最优雅的方法如下:
class Message < ActiveRecord::Base
cattr_accessor :skip_callbacks
before_save lambda { foo(publisher); bar }, :unless => :skip_callbacks # let's say you do not want this callback to be triggered when you perform batch operations
end
Then, you can do:
然后,你可以这样做:
Message.skip_callbacks = true # for multiple records
my_message.update_attributes(:created_at => ...)
Message.skip_callbacks = false # reset
Or, just for one record:
或者,仅针对一个记录:
my_message.update_attributes(:created_at => ..., :skip_callbacks => true)
If you need it specifically for a Timeattribute, then touchwill do the trick as mentioned by @lucapette .
如果您专门为某个Time属性需要它,那么touch将执行@lucapette 提到的技巧。
回答by fl00r
update_allwon't trigger callbacks
update_all不会触发回调
my_message.update_all(:created_at => ...)
# OR
Message.update_all({:created_at => ...}, {:id => my_message.id})
回答by nathanvda
You could also make your before_saveaction conditional.
你也可以让你的before_save行动有条件。
So add some field/instance variable, and set it only if you want to skip it, and check that in your method.
因此,添加一些字段/实例变量,仅当您想跳过它时才设置它,并在您的方法中检查它。
E.g.
例如
before_save :do_foo_and_bar_if_allowed
attr_accessor :skip_before_save
def do_foo_and_bar_if_allowed
unless @skip_before_save.present?
foo(publisher)
bar
end
end
and then somewhere write
然后在某处写
my_message.skip_before_save = true
my_message.update_attributes(:created_at => ...)
回答by Archonic
update_columnor update_columnsis the closest method to update_attributesand it avoids callbacks without having to manually circumvent anything.
update_columnorupdate_columns是最接近的方法update_attributes,它避免了回调,而无需手动规避任何事情。

