23

我有一個before_save在這樣定義我Message型號:如何在不執行「before_save」的情況下「update_attributes」?

class Message < ActiveRecord::Base 
    before_save lambda { foo(publisher); bar } 
    end 

當我這樣做:

my_message.update_attributes(:created_at => ...) 

foobar被執行。

有時,我想更新消息的字段而不執行foobar

我怎麼能更新,例如,created_at字段(在數據庫中)而不執行foobar

回答

33

在rails 3.1中,您將使用update_column

否則:

在一般的方式,繞過回調最優雅的方式如下:

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 

然後,你可以這樣做:

Message.skip_callbacks = true # for multiple records 
my_message.update_attributes(:created_at => ...) 
Message.skip_callbacks = false # reset 

或者,只是一個記錄:

my_message.update_attributes(:created_at => ..., :skip_callbacks => true) 

如果您需要專用於Time屬性,那麼touch將執行@lucapette所述的技巧。

+0

看起來像一個很好的通用解決方案!一個問題:究竟是什麼'Message.batch = true'呢? –

+0

這只是一面旗幟。你可以用任何你想要的來代替它。 – jbescoyez

+0

我已經用更明確的標誌更新了示例。 – jbescoyez

17

update_all不會觸發回調

my_message.update_all(:created_at => ...) 
# OR 
Message.update_all({:created_at => ...}, {:id => my_message.id}) 

http://apidock.com/rails/ActiveRecord/Base/update_all/class

+1

'my_message.update_all(:created_at => ...)'發出語法錯誤,但第二個選項正常工作! –

+1

my_message.update_all將觸發'未定義的方法update_all'。 Message.update_all將會訣竅 –

+0

你可能可以使用increment_counter [如果它是一個你想增加的計數器],我相信它也會跳過回調。 – rogerdpack

6

使用touch方法。這是優雅的,而不是你想要的

+0

看起來像我需要的東西。在我的情況下,'created_at'的新值是**而不是當前時間。 –

+0

哦,有趣:) – fl00r

+0

@Misha你顯然是對的。所以你可以使用http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_attribute:D – lucapette

1

您還可以使您的before_save操作有條件。

因此,添加一些字段/實例變量,並且僅在您想要跳過它時進行設置,並在您的方法中檢查該變量。

例如

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

update_columnupdate_columnsupdate_attributes最接近方法和它避免了回調而無需手動規避任何東西。

相關問題