SakuraWi - BLog

みんなのウェディングの新米エンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

update_attributesとupdate_columnsの違い【Ruby on Rails】


Ruby on RailsのTutorialで使用されている、update_columns
そして似たような処理に見える update_attributesがあります。

この二つの違いについて調べてみたことをまとめます。

検索するとqiitaの以下の記事がでてきますね。
どうもこちらの記事によるとバリデーションやコールバックの違いがあるようです。
ActiveRecord の attribute 更新方法まとめ - Qiita

しかし!
最近よく言われますが、公式ドキュメントを参照するのが一番です。
なに?英語が読めない?
読めるようになればいいだけです。 そして読めるようになるには、読む練習が必要です。(自分に言い聞かせる)

ということでこちらも目を通しましょう。

ActiveRecord::Persistence

公式ドキュメント

update_attribute(name, value)

  • Validation is skipped.
  • Callbacks are invoked.
  • updated_at/updated_on column is updated if that column is available.
  • Updates all the attributes that are dirty in this object.

これは,

  • ヴァリデーションはされません
  • コールバックは呼ばれます
  • updated_atか_onのカラムが利用可能であれば更新されます
  • dirty,検知が可能である(変更があったかどうかがわかる) という風に書いていますね。

太字の二つは他のメソッドと異なる場合が多いので注目ですね。

update_attributes(attributes) / update(attributes)

こちらは上記のsがないバージョンですね。
updateは、エイリアスでupdate_attiributeと同様の処理となります。
動きが結構違うのでしっかりと見ておきましょう。

  • ヴァリデーションが適用される
  • コールバックが呼ばれる

ここがポイントです。
また、複数のカラムを同時に更新できるため、タイミングを同じタイミングで更新したいカラムがある場合にはこちらを使用します。

update_columns(attributes)

最後に、update_columnsです。 Rails Tutorialででてきましたね。

公式ドキュメントによると、

-validations are skipped. -Callbacks are skipped. -updated_at/updated_on are not updated. -However, attributes are serialized with the same rules as ActiveRecord::Relation#update_all

とのことです。

  • ヴァリデーションは適用されない
  • コールバックは呼ばれない
  • 更新の履歴は updated_atなどに残らない(更新されない)
  • update_allと同様にシリアライズされる

4つ目については、update_allの箇所で以下のように示されています。

However, values passed to update_all will still go through Active Record’s normal type casting and serialization.

キャストとシリアライズが行われる、となっていますね。 シリアライズというのは、配列のままDBに保存する時などに行われる変換のようです。

使用例

以下の2行の書き換え例ですね。 Tutorialでは、columnsを使っていました。

 update_attribute(:activated, true)
 update_attribute(:activated_at, Time.zone.now)
update_columns(activated: true, activated_at: Time.zone.now)
update_attributes(activated: true, activated_at: Time.zone.now )

まとめ

基本的にはvalidationとcallbackが行われる、
update_attributesを使用しましょう!

参考記事、URL

Rails Tutorial 11章,12章

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう