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 => ...)