- Ruby / Rails関連
Railsのタイムスタンプカラム(created_at, updated_at)を別名で動かす(create_date, update_dateなど)
はじめに
本記事は Rails のタイムスタンプ カラム(created_at
, updated_at
)を別名で動かす(create_date
, update_date
など) 方法をご紹介します。(Rails 7において、動作確認をしています。)
たとえば、既存アプリケーションのシステム移行などで DB 構成は変えずに他の言語から Rails へ移行させる場合などで、既存のカラムが create_date
update_date
などと定義されており、それぞれレコード作成日時や更新日時を入れたい、などの要望がある場合に役に立ちそうです。
タイムスタンプカラムを別名で動かす方法
たとえば、以下のようなテーブルがあるとします。
テーブル名: users
カラム名 | 型 |
---|---|
id | bigint |
string | |
create_date | datetime |
update_date | datetime |
上記のケースの場合 モデルに以下の記述をすると、それぞれ作成日時、更新日時がcreate_date
、update_date
カラムに自動的に入ってくるようになります。🎉
# app/models/user.rb
class User < ApplicationRecord
self.attribute_aliases = { 'created_at' => 'create_date', 'updated_at' => 'update_date' }
...
end
また以下のように ファイルを分けて書き、必要なモデルでインクルードする形をとると、よりいい感じかなと思います。
# app/models/concerns/timestampable.rb
module Timestampable
extend ActiveSupport::Concern
included do
# タイムスタンプカラム上書き
self.attribute_aliases = { 'created_at' => 'create_date', 'updated_at' => 'update_date' }
end
end
# app/models/user.rb
class User < ApplicationRecord
include Timestampable
...
end
なぜ動くか?
なぜ動くかについてですが、ポイントになるのが、Rails のtimestamp_attributes_for_create
、timestamp_attributes_for_update
メソッドの定義箇所です。
# rails/activerecord/lib/active_record/timestamp.rb
module ActiveRecord
module Timestamp
...
private
def timestamp_attributes_for_create
["created_at", "created_on"].map! { |name| attribute_aliases[name] || name }
end
def timestamp_attributes_for_update
["updated_at", "updated_on"].map! { |name| attribute_aliases[name] || name }
end
...
end
end
上記のメソッドについて、それぞれタイムスタンプの役割を担うカラムの名前(の配列)を返しているものと思われます。
このため、メソッドのロジックより、attribute_aliases
(デフォルトでは、空のハッシュ) にそれぞれデフォルトのタイムスタンプ名をKey(※必ずシンボルでなく文字列で ⚠️ )、新しくタイムスタンプのカラムにしたいものをValue でハッシュ更新するとcreated_at(updated_at)
カラムと同様な動きをしてくれるようになる、ということでした。
以上、参考になればうれしいです。
参考:Rails テーブルの作成更新日時のカラム名を変更する。