ActiveRecord コールバックの実行を回避するにはどうすればよいですか?
概要
after_save コールバックを持つモデルがいくつかあります。通常はこれで問題ありませんが、開発データの作成時など、コールバックを実行せずにモデルを保存したい場合があります。それを行う簡単な方法はありますか?似たような何か…
Person#save( :run_callbacks => false )
または
Person#save_without_callbacks
Rails のドキュメントを調べましたが、何も見つかりませんでした。ただし、私の経験では、Rails ドキュメントが必ずしもすべてを伝えているわけではありません。
アップデート
次のようなモデルからコールバックを削除する方法を説明したブログ投稿を見つけました。
Foo.after_save.clear
その方法が文書化されている場所を見つけることができませんでしたが、機能するようです。
解決策
コールバックと検証をスキップするには、update_column (Rails >= v3.1) または update_columns (Rails >= 4.0) を使用します。これらのメソッドでも、updated_at は更新されません。
#Rails >= v3.1 only
@person.update_column(:some_attribute, 'value')
#Rails >= v4.0 only
@person.update_columns(attributes)
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column
#2: オブジェクトの作成中にも機能するコールバックのスキップ
class Person < ActiveRecord::Base
attr_accessor :skip_some_callbacks
before_validation :do_something
after_validation :do_something_else
skip_callback :validation, :before, :do_something, if: :skip_some_callbacks
skip_callback :validation, :after, :do_something_else, if: :skip_some_callbacks
end
person = Person.new(person_params)
person.skip_some_callbacks = true
person.save
更新情報 (2020)
どうやら Rails は常に :if および :unless オプションをサポートしているため、上記のコードは次のように簡略化できます。
class Person < ActiveRecord::Base
attr_accessor :skip_some_callbacks
before_validation :do_something, unless: :skip_some_callbacks
after_validation :do_something_else, unless: :skip_some_callbacks
end
person = Person.new(person_params)
person.skip_some_callbacks = true
person.save