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

ActiveRecordの属性を変えずにupdateしてもupdated_atは更新せず、余計なSQLを発行しないので便利

概要

ActiveRecordを継承したモデルで属性値を変えずにupdateメソッドを実行しても、更新するSQL自体実行しない。
更新日付のupdate_atも更新されない。

モデルの値を変えないというのは明示的に属性値を変える前と同じ値を代入しても同様に更新するSQL自体実行しない。

前提条件

Rails: 5.2
Ruby: 2.5.1

本題

サンプルのユーザテーブルの定義

create_table :users do |t|
  t.string :name
  t.timestamps
end

ユーザモデルの定義

class User < ApplicationRecord
end

サンプル用に適当なUserモデルを作成しupdated_atを表示する

User.first.updated_at
=> Tue, 29 Jan 2019 03:56:08 UTC +00:00
User.first.updated_at.to_i
=> 1548734168

name属性を、Userモデルに元々入っていた値でupdateする。
後述する変更した場合と比べると、UPDATE文のSQLが実行されないことがわかる
実行結果のupdated_atが、updateメソッド実行前のupdate_atと同じ1548734168で有ることがわかる

> User.first.update!(name: User.first.name)
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.1ms)  begin transaction
   (0.0ms)  commit transaction
=> true
irb(main):008:0> User.first.updated_at.to_i
=> 1548734168

検証ついでにname属性の値を変更すると、UPDATE文のSQLが実行され、updated_atの値が更新されることがわかる

> User.first.update!(name: User.first.name + "1")
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.1ms)  begin transaction
  User Update (1.3ms)  UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["name", "テスト1"], ["updated_at", "2019-02-01 08:27:12.468565"], ["id", 2]]
   (2.9ms)  commit transaction
=> true

> User.first.updated_at.to_i
  User Load (0.3ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 1549009632
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
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