■ 1. 主張
- created_at にドメインロジックを持たせない:
- ActiveRecord のマイグレーションでは
t.timestampsがデフォルト指定され、created_at と updated_at が付与される- これらのカラムはレコードの作成・更新を記録するメタデータとしてのみ利用する
- where や sort の条件に使わない:
- アプリケーション内で created_at を検索条件や並び替え条件として利用することは避ける
- メタデータ以上の用途に広げると辛くなる
■ 2. created_at の意味の変質
- created_at が指す日時:
- created_at は「レコードが作成された日時」を意味する
- 「レコードが記録されたイベントが発生した日時」ではない
- 集計条件としての違和感:
- 月間に発生した件数を集計する条件は「そのイベントが行われた期間」とするのが自然
- 「レコードが作成された期間」を条件とするのは違和感がある
- 不整合修正時に生じる矛盾:
- 前月に発生したデータの不整合をレコード1件の追加で直す場合を想定する
- created_at を集計条件にしていると、追加するレコードの created_at を前月にして insert する必要が生じる
- そのような操作は違和感がある
■ 3. 対応方針
- 専用の timestamp カラムを用意:
- 何らかのアクションが行われた日付を取りたいのであれば、別途そのためのカラムを timestamp で持つ
- イベントテーブルの例:
- 注文が配送された日時を記録したいのであれば
shipped_atを用意する- order has_one shipment のようにイベントテーブルを作り、その上で
shipped_atを作る■ 4. 想定される反論への応答
- timestamp が不要なテーブルの発生:
- タイムスタンプが不要なテーブルも出てくるという指摘はそのとおり
- ActiveRecord がデフォルトで timestamp を付与するため、そのままにしているだけ
- 必要になってから増やすという考え:
- 必要になってからカラムを増やすという考えも正しい
- ただし、それを判断できるメンバーがいつも開発フローの場にいるとは限らない
- 結果として created_at を条件に集計ロジックを書く人が出てくる
- 最初からカラムを作る利点:
- 最初からカラムを作っておけば、将来開発するメンバーが迷わない
- created_at や updated_at を条件にするならカラムをマイグレーションしろ、とAIエージェントに全員が依頼するとは限らない
■ 5. 他の論者の意見
- Songmu 氏の記事:
- 以前に拝見したことがあり、ほとんど同じ内容を書いてしまった
- 神速さんの post から派生した議論:
- neko314 氏の記事はとても丁寧な主張
- hanachin 氏の記事は逆の意見で、必要になってから考えるという立場
- そうした考えがあってもよい
■ 6. 背景と補足
- 既存DBにRailsを被せた歴史:
- 業務で扱っているサービスが既存のデータベースの上に Rails を被せている歴史を持つ
- そうした事情があるためにこの考えに至ったのかもしれない
- 実装の所在:
- created_at と updated_at の実装は ActiveRecord::Timestamp にある