[解決済み] Railsで属性が変更されたときだけコールバックを実行する
質問
私のアプリには、次のような関連付けがあります。
# Page
belongs_to :status
を実行したときに、いつでもコールバックを実行できるようにしたい。
status_id
の
page
が変更されました。
では、もし
page.status_id
が4から5になった場合、それをキャッチできるようにしたいのです。
どうすればいいのでしょうか?
どのように解決するのですか?
Rails 5.1以上
class Page < ActiveRecord::Base
before_save :do_something, if: :will_save_change_to_status_id?
private
def do_something
# ...
end
end
ActiveRecord::Dirtyを変更したコミットはこちらです。 https://github.com/rails/rails/commit/16ae3db5a5c6a08383b974ae6c96faac5b4a3c81
この変更に関するブログ記事はこちらです。 https://www.fastruby.io/blog/rails/upgrades/active-record-5-1-api-changes
Rails 5.1+のActiveRecord::Dirtyの変更点について、自分用にまとめたものです。
ActiveRecord::Dirty (アクティブレコード::ダーティ)
https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html
保存前 (オプション変更)
オブジェクトを変更した後、データベースに保存する前、または、オブジェクトの中にある
before_save
フィルタを使用することができます。
-
changes
は、現在ではchanges_to_save
-
changed?
は、現在has_changes_to_save?
-
changed
は、現在changed_attribute_names_to_save
-
<attribute>_change
は、現在<attribute>_change_to_be_saved
-
<attribute>_changed?
は、現在will_save_change_to_<attribute>?
-
<attribute>_was
は、現在<attribute>_in_database
保存後 (ブレイキング・チェンジ)
オブジェクトを変更した後、データベースに保存した後、あるいは
after_save
フィルタを使用することができます。
-
saved_changes
(代わりにprevious_changes
) -
saved_changes?
-
saved_change_to_<attribute>
-
saved_change_to_<attribute>?
-
<attribute>_before_last_save
Rails <= 5.0
class Page < ActiveRecord::Base
before_save :do_something, if: :status_id_changed?
private
def do_something
# ...
end
end
これは
before_save
コールバックがメソッド呼び出しの戻り値に基づいて条件付きで実行できることを利用しています。そのため
status_id_changed?
メソッドの由来は
ActiveModel::Dirty
を追加するだけで、特定の属性が変更されたかどうかを確認することができます。
_changed?
を属性名に加えるだけで、特定の属性が変更されたかどうかを確認することができます。
の場合は
do_something
メソッドを呼び出すかどうかは、あなたのニーズ次第です。例えば
before_save
あるいは
after_save
または
定義されたActiveRecord::Callbacksは
.
関連
-
[解決済み] Oauth2 Instagram API "リダイレクトURIが登録されたリダイレクトURIと一致しない"
-
[解決済み] Ruby: public static メソッドを作るには?
-
[解決済み] Railsはsaveでモデル内の検証をスキップしますか?
-
[解決済み] 構文エラー "構文エラー、予期しない入力終了、keyword_endを期待 (SyntaxError)"
-
[解決済み] Ruby on Rails の新規セットアップ : "Expected string default value for '--rc'; got false (boolean)".
-
[解決済み] コールバック内で正しい `this` にアクセスする方法
-
[解決済み] rake db:migrate db:reset とdb:schema:loadの違いについて
-
[解決済み】railsでカスタム設定変数を定義する方法
-
[解決済み】jQueryはコールバックに多くのパラメータを渡します。
-
[解決済み] Railsのafter_saveコールバックでどの属性が変更されたかを判定しますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Bundler: コマンドが見つからない
-
[解決済み】取得中。「プロジェクトのクローンとマイグレート後に、「マイグレーションは保留中です。この問題を解決するには 'bin/rake db:migrate RAILS_ENV=development' を実行してください。
-
[解決済み] Ruby/Rails の「フック」とは何ですか?
-
[解決済み] Ruby on rails "No route matches" (ルートに一致するものがない)。
-
[解決済み] rspec 3 - クラスメソッドをスタブ化する
-
[解決済み] Ruby on Railsのためにnetbeansを構成する方法は?
-
[解決済み] Railsです。gemを使った特定バージョンのライブラリのアンインストール
-
[解決済み] railsアプリケーションでCookieのオーバーフロー?
-
[解決済み] gemのアップデート後、"Asset was not declared to be precompiled in production "でテストが失敗する。
-
[解決済み] レイル 4 radio_button_tag default not selected