LoginSignup
0

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す7(touch_all 編)

Last updated at Posted at 2019-04-24

はじめに

Rails 6 に追加されそうな新機能を試す第7段。 今回のちょい足し機能は、日時を(現在時刻に)一気に更新するメソッド touch_all 編です。
記載時点では、Rails は 6.0.0.beta3 です。 gem install rails --prerelease でインストールできます。

$  rails --version
Rails 6.0.0.beta3

単純な model を作る

新機能を試すために、Book model を作ります。出版時刻なんてあるのかよというツッコミは無しでお願いします。

$ rails new sandbox_6_0_0b3
$ cd sandbox_6_0_0b3
$ rails g model Book title published_at:datetime
$ rails db:migrate

データ 2件作ります。

$ bin/rails c
irb(main):001:0> Book.new(title: 'Ruby Book',  published_at: Time.now - 10.year).save
   (0.2ms)  BEGIN
  Book Create (0.4ms)  INSERT INTO "books" ("title", "published_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["title", "Ruby Book"], ["published_at", "2009-04-24 11:23:20.452962"], ["created_at", "2019-04-24 11:23:20.474368"], ["updated_at", "2019-04-24 11:23:20.474368"]]
   (1.2ms)  COMMIT
=> true
irb(main):002:0> Book.new(title: 'Rails Book',  published_at: Time.now - 5.year).save
   (0.4ms)  BEGIN
  Book Create (0.7ms)  INSERT INTO "books" ("title", "published_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["title", "Rails Book"], ["published_at", "2014-04-24 11:23:41.370049"], ["created_at", "2019-04-24 11:23:41.370751"], ["updated_at", "2019-04-24 11:23:41.370751"]]
   (7.2ms)  COMMIT
=> true
irb(main):003:0> Book.all
  Book Load (0.7ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[
#<Book id: 2, title: "Ruby Book", published_at: "2009-04-24 11:23:20", created_at: "2019-04-24 11:23:20", updated_at: "2019-04-24 11:23:20">, 
#<Book id: 3, title: "Rails Book", published_at: "2014-04-24 11:23:41", created_at: "2019-04-24 11:23:41", updated_at: "2019-04-24 11:23:41">
]>
irb(main):005:0>

touch_all を使ってみます。 (Book.all の結果はわかりやすいように改行を入れました。)

引数なしで touch_all

touch_all を引数なしで実行すると updated_at が現在時刻に更新されます。

irb(main):007:0> Book.all.touch_all
  Book Update All (7.6ms)  UPDATE "books" SET "updated_at" = $1  [["updated_at", "2019-04-24 11:38:54.990656"]]
=> 2
irb(main):008:0> Book.all
  Book Load (0.8ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[
#<Book id: 2, title: "Ruby Book", published_at: "2009-04-24 11:23:20", created_at: "2019-04-24 11:23:20", updated_at: "2019-04-24 11:38:54">, 
#<Book id: 3, title: "Rails Book", published_at: "2014-04-24 11:23:41", created_at: "2019-04-24 11:23:41", updated_at: "2019-04-24 11:38:54">
]>

touch_all(column)

touch_all の引数にカラムを指定すると指定したカラムと updated_at が現在時刻に更新されます。
where と組み合わせることもできます。
(Ruby Book の published_atupdated_at が現在時刻に更新されます。)

irb(main):009:0> Book.where(title: 'Ruby Book').touch_all(:published_at)
  Book Update All (8.2ms)  UPDATE "books" SET "updated_at" = $1, "published_at" = $2 WHERE "books"."title" = $3  [["updated_at", "2019-04-24 11:40:16.201803"], ["published_at", "2019-04-24 11:40:16.201803"], ["title", "Ruby Book"]]
=> 1
irb(main):010:0> Book.all
  Book Load (0.7ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[
#<Book id: 3, title: "Rails Book", published_at: "2014-04-24 11:23:41", created_at: "2019-04-24 11:23:41", updated_at: "2019-04-24 11:38:54">, 
#<Book id: 2, title: "Ruby Book", published_at: "2019-04-24 11:40:16", created_at: "2019-04-24 11:23:20", updated_at: "2019-04-24 11:40:16">
]>

touch_all(column1, column2, ...)

touch_all の引数に複数のカラムを指定することもできます。
(Rails Book の created_at , updated_at , published_at が現在時刻に更新されます。)

irb(main):011:0> Book.where(title: 'Rails Book').touch_all(:published_at, :created_at)
  Book Update All (7.8ms)  UPDATE "books" SET "updated_at" = $1, "published_at" = $2, "created_at" = $3 WHERE "books"."title" = $4  [["updated_at", "2019-04-24 11:54:03.981679"], ["published_at", "2019-04-24 11:54:03.981679"], ["created_at", "2019-04-24 11:54:03.981679"], ["title", "Rails Book"]]
=> 1
irb(main):012:0> Book.all
  Book Load (0.9ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation
[
#<Book id: 2, title: "Ruby Book", published_at: "2019-04-24 11:40:16", created_at: "2019-04-24 11:23:20", updated_at: "2019-04-24 11:40:16">, 
#<Book id: 3, title: "Rails Book", published_at: "2019-04-24 11:54:03", created_at: "2019-04-24 11:54:03", updated_at: "2019-04-24 11:54:03">
]>

touch_all(column1, column2,..., time: xxx)

touch_all の引数に time: xxxx で指定した時刻に更新することもできます。
(Rails Book の created_at , updated_at , published_at が 3年前に更新されます。)

irb(main):013:0> Book.where(title: 'Rails Book').touch_all(:published_at, :created_at, time: Time.now - 3.year)
  Book Update All (7.3ms)  UPDATE "books" SET "updated_at" = $1, "published_at" = $2, "created_at" = $3 WHERE "books"."title" = $4  [["updated_at", "2016-04-24 11:59:16.030048"], ["published_at", "2016-04-24 11:59:16.030048"], ["created_at", "2016-04-24 11:59:16.030048"], ["title", "Rails Book"]]
=> 1
irb(main):014:0> Book.all
  Book Load (0.8ms)  SELECT "books".* FROM "books" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation 
[
#<Book id: 2, title: "Ruby Book", published_at: "2019-04-24 11:40:16", created_at: "2019-04-24 11:23:20", updated_at: "2019-04-24 11:40:16">, 
#<Book id: 3, title: "Rails Book", published_at: "2016-04-24 11:59:16", created_at: "2016-04-24 11:59:16", updated_at: "2016-04-24 11:59:16">
]>
irb(main):015:0>

touch_all 実行時の callback や validation

touch_all は内部で update_all を呼び出していて、touch_all が実行されるときに、callback や validation は実行されません。

参考情報

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
0