24

モデルに次のように定義さbefore_saveれています。Message

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

私がする時:

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

foobar実行されます。

fooおよびを実行せずにメッセージのフィールドを更新したい場合がありbarます。

たとえば、実行せずに(データベース内の)フィールドを更新するにはどうすればよいですcreated_atか?foobar

4

5 に答える 5

35

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

または、1つのレコードについて:

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

Time特に属性に必要な場合はtouch、@lucapetteで説明されているようにトリックを実行します。

于 2011-08-30T13:33:35.427 に答える
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

于 2011-08-30T13:18:14.040 に答える
6

タッチ方式を採用。それはエレガントで、あなたが望むものを正確に実行します

于 2011-08-30T13:19:43.643 に答える
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 => ...)
于 2011-08-30T13:34:00.607 に答える