Ruby on rails 如何";更新“U属性”;不执行;在“保存”之前;?
在我的Ruby on rails 如何";更新“U属性”;不执行;在“保存”之前;?,ruby-on-rails,ruby-on-rails-3,before-filter,update-attributes,before-save,Ruby On Rails,Ruby On Rails 3,Before Filter,Update Attributes,Before Save,在我的消息模型中,我在保存之前有一个,定义如下: class Message < ActiveRecord::Base before_save lambda { foo(publisher); bar } end 执行foo和bar 有时,我想在不执行foo和bar的情况下更新消息的字段 例如,我如何在不执行foo和bar的情况下更新created\u字段(在数据库中)?update\u all不会触发回调 my_message.update_all(:create
消息
模型中,我在保存之前有一个,定义如下:
class Message < ActiveRecord::Base
before_save lambda { foo(publisher); bar }
end
执行foo
和bar
有时,我想在不执行foo
和bar
的情况下更新消息的字段
例如,我如何在不执行foo
和bar
的情况下更新created\u字段(在数据库中)?update\u all
不会触发回调
my_message.update_all(:created_at => ...)
# OR
Message.update_all({:created_at => ...}, {:id => my_message.id})
使用该方法。它非常优雅,完全符合您在rails 3.1中将要使用的功能
否则:
一般来说,最优雅的绕过回调的方法如下:
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
或者,就一张唱片而言:
my_message.update_attributes(:created_at => ..., :skip_callbacks => true)
如果您特别需要它作为时间
属性,那么触摸
将完成@lucapete提到的技巧。您也可以在保存操作之前设置
因此,添加一些字段/实例变量,仅当您想跳过它时才设置它,并在方法中检查它
例如
然后在某处写信
my_message.skip_before_save = true
my_message.update_attributes(:created_at => ...)
update\u column
或update\u columns
是最接近update\u attributes
的方法,它避免了回调,而无需手动规避任何问题。看起来几乎就是我需要的。在我的例子中,
创建的新值不是当前时间。@Misha你显然是对的。因此,您可以使用:D@lucapette:怎么做?文档说,update\u属性
调用回调。@Misha您不能。考虑到你的问题,我把回调和验证混淆了。。。所以我认为你应该使用所有的更新。顺便说一句,我可能忽略了我的消息。update\u all(:created\u at=>…)
会发出语法错误,但第二个选项工作正常!my_message.update_all将触发未定义的方法update_all
。Message.update\u all就可以了。我相信,你可以使用increment\u counter[如果你想增加计数器的话],它也可以跳过回调。要使用实例,你可以使用或避免回调,这是一个很好的通用解决方案!有一个问题:Message.batch=true
到底要做什么?它只是一个标志。您可以用任何需要的内容替换它。这对序列化列(即update_列)不起作用,因为出于某种原因,它也会跳过序列化/反序列化。值得注意的是,使用update_列还意味着不会运行验证。由于您正在类上设置属性,因此这似乎不是非常线程安全的。思想?
my_message.update_attributes(:created_at => ..., :skip_callbacks => true)
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
my_message.skip_before_save = true
my_message.update_attributes(:created_at => ...)