みなさん、こんにちは。
今年は久しぶりに花粉の影響が強く苦しんでいる小林です。
また一つ、Ruby on Rails(以下、Rails)の謎が解けたので、紹介したいと思います。
今回のテーマは、こちらです。
timestampsマクロは何をしているのか?
timestampsマクロは何をしているのか?
timestampsマクロとは何か?
timestampsを呼び出すと作成日時(created_at)、更新日時(updated_at)を自動的に作成してくれます。
# db/migrate/2023032562631_create_products.rb
class CreateProducts < ActiveRecord::Migration[7.0]
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
sample=# \d products
id | bigint | | not null | nextval('products_id_seq'::regclass)
name | character varying | | |
description | text | | |
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
(↑うまく整形できなかったので、諦めました。)
Railsガイドにも記載されています。
timestampsマクロは、created_atとupdated_atという2つのカラムを追加します。これらの特殊なカラムが存在する場合、Active Recordによって自動的に管理されます。
使用する分にはこれで十分なのですが、中で何をやっているのだろうと気になってしまったのが事の始まりでした。
何をしているのか?
結論から言うと、さほど複雑なことはしていませんでした。
active_record/connection_adapters/abstract/schema_definitions.rb#L460-L469
def timestamps(**options)
options[:null] = false if options[:null].nil?
if !options.key?(:precision) && @conn.supports_datetime_with_precision?
options[:precision] = 6
end
column(:created_at, :datetime, **options)
column(:updated_at, :datetime, **options)
end
要は、自身で以下のように書けるけど、timestampsマクロを使用すれば、記述量が減らせて楽ですよ。ということです。
# db/migrate/2023032562631_create_products.rb
class CreateProducts < ActiveRecord::Migration[7.0]
def change
create_table :products do |t|
t.string :name
t.text :description
t.datetime :created_at, null: false, precision: 6
t.datetime :updated_at, null: false, precision: 6
end
end
end
最後に
今回は、仕組みが複雑怪奇というよりも、どこで定義されているかが見つけられずにもやもやしていたので、読み込みが足りないなと痛感しました。

