はじめに
タイトル通りです。
下のアプリはチャットルームに「タイトル」と「ルームの説明」、「カテゴリ」を設定できるんだけれども、
「タイトル」が変更された時だけトークルームに通知が来るようにしたかった。
変更前のパラメーターを取得するか、変更されたかどうかを判定するメソッドがあったら嬉しいなーと思って探した。
実装
どうやらActiveRecordさんには「カラム名_changed?」っていうヘルパーメソッドがあるらしいと聞いて...
def update
if @room.update(room_update_params)
if @room.title_changed? # ココ。title_cahged?がtrueであれば自動メッセージを送るようにしたつもり。
Message.create(room_id: @room.id, user_id: current_user.id, content: "*自動投稿* タイトルを「#{@room.title}」に編集しました")
end
redirect_to room_path(@room.id)
else
render :edit
end
end
こんな感じで実装してみたのだけれども失敗した。
Githubのrailsを見てみると、なんか更新されているらしい。
つまり
カラム名_changed?は、ActiveRecordのコールバックを使って処理を分けることができていたが、
save前の場合は、
オブジェクト.will_save_change_to_カラム名
save後の場合は、
オブジェクト.saved_change_to_{カラム名}?
という風に書き変える必要があるみたい。
再度実装
def update
if @room.update(room_update_params)
if @room.title_updated?
Message.create(room_id: @room.id, user_id: current_user.id, content: "*自動投稿* タイトルを「#{@room.title}」に編集しました")
end
redirect_to room_path(@room.id)
else
render :edit
end
end
コントローラーで「saved_change_to」やら「will_save_change_to」やらを呼び出すとうまくいかなかったので、
モデル側に「更新されたかどうか判別するインスタンスメソッド」を作りました。
def title_updated?
if self.saved_change_to_title?
return true
else
return false
end
end
これでタイトル編集時のみメッセージが投稿されるようになりました。
おわりに
今回初めてrailsのソースコードを見ましたが、もっと見ていくととても勉強になりそうです。
暇を見つけてもっと読んでみようと思いました。
おわり。