LoginSignup
11
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-01

概要

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
11
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6