はじめに
Rails 6 に追加された新機能を試す第87段。 今回は、 Time#advance
編です。
Rails 6 では、 1001/03/07 以前の Time#advance
の計算が正確になりました。
Ruby 2.6.4, Rails 6.0.0 Rails 5.2.3 で確認しました。
$ rails --version
Rails 6.0.0
今回は、ちょっとわざとらしいですが、2009年4月1日の1200年前に即位した天皇を検索してみましょう。
プロジェクトを作る
rails new rails_sandbox
cd rails_sandbox
Emperor モデルを作る
name
と enthroned_at
(即位した年) をもつ Emperor
モデルを作ります。
bin/rails g model Emperor name enthroned_at:datetime
seed データを作る
seed
データを作ります。
db/seeds.rb
Emperor.create(
[
{ name: '桓武天皇', enthroned_at: Time.utc(781, 4, 3) },
{ name: '平城天皇', enthroned_at: Time.utc(806, 3, 17) },
{ name: '嵯峨天皇', enthroned_at: Time.utc(809, 4, 1) },
{ name: '淳和天皇', enthroned_at: Time.utc(823, 4, 16) },
{ name: '仁明天皇', enthroned_at: Time.utc(833, 2, 28) }
]
)
マイグレーションを行い seed データを登録する
$ bin/rails db:create db:migrate db:seed
rails console で確認する
enthroned_at
が 2009年4月1日の 1200年前に即位した天皇を検索してみます。
「2009年4月1日の 1200年前」は、 Time.utc(2009, 4, 1).advance(years: 1200)
で求めることができます。
irb(main):001:0> Emperor.where(enthroned_at: Time.utc(2009, 4, 1).advance(years: -1200))
Emperor Load (0.3ms) SELECT "emperors".* FROM "emperors" WHERE "emperors"."enthroned_at" = $1 LIMIT $2 [["enthroned_at", "0809-04-01 00:00:00"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Emperor id: 3, name: "嵯峨天皇", enthroned_at: "0809-04-01 00:00:00", created_at: "2019-09-21 21:49:24", updated_at: "2019-09-21 21:49:24">]>
嵯峨天皇が検索できました。
Rails 5.2.3 では
「2009年4月1日の 1200年前」が 809年4月5日になってしまうため、期待した結果が得られません
irb(main):001:0> Emperor.where(enthroned_at: Time.utc(2009, 4, 1).advance(years: -1200))
Emperor Load (0.5ms) SELECT "emperors".* FROM "emperors" WHERE "emperors"."enthroned_at" = $1 LIMIT $2 [["enthroned_at", "0809-04-05 00:00:00"], ["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
試したソース
試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try087_time_advance