Help us understand the problem. What is going on with this article?

[Rails] ActiveRecordでデータを更新したときに、各カラムが更新されたかどうか知りたかったんだ

はじめに

タイトル通りです。

下のアプリはチャットルームに「タイトル」と「ルームの説明」、「カテゴリ」を設定できるんだけれども、
「タイトル」が変更された時だけトークルームに通知が来るようにしたかった。
Image from Gyazo

変更前のパラメーターを取得するか、変更されたかどうかを判定するメソッドがあったら嬉しいなーと思って探した。

実装

どうやらActiveRecordさんには「カラム名_changed?」っていうヘルパーメソッドがあるらしいと聞いて...

room_controller
  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_{カラム名}?

という風に書き変える必要があるみたい。

再度実装

room_controller.rb
  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」やらを呼び出すとうまくいかなかったので、
モデル側に「更新されたかどうか判別するインスタンスメソッド」を作りました。

room.rb
  def title_updated?
    if self.saved_change_to_title?
      return true
    else
      return false
    end
  end

これでタイトル編集時のみメッセージが投稿されるようになりました。

Image from Gyazo

おわりに

今回初めてrailsのソースコードを見ましたが、もっと見ていくととても勉強になりそうです。
暇を見つけてもっと読んでみようと思いました。

おわり。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした