Tech Racho エンジニアの「?」を「!」に。
  • 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
email string
create_date datetime
update_date datetime

上記のケースの場合 モデルに以下の記述をすると、それぞれ作成日時、更新日時がcreate_dateupdate_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_createtimestamp_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 テーブルの作成更新日時のカラム名を変更する。



CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。