ActiveRecordのTimestampについて
config.rbの設定
config.active_record.record_timestamps = false
activerecordのtimestampをon/offする設定できる。
config.active_record.default_timezone = :local
デフォルトはUTCであるが、ローカルのタイムゾーンを設定できる。
config.active_record.time_zone_aware_attributes = false
ActiveRecordの全てのdatetime、timeカラムをタイムゾーンに対応させる。
デフォルトではUTCとしてDBに保存を行い、取得するときはTime.zoneを変換する。
ActiveRecord::Base.time_zone_aware_types = [:datetime] or [:time]
datetime、timeのみを設定することも可能
ActiveRecord::Base.record_timestamps = false
timestampの自動更新を一括offにできる
Railsのソースコードを読んでみた
active_recordのtimestampについて調べてみました。主にここをみてます。
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/timestamp.rb
create時
def _create_record
if record_timestamps
current_time = current_time_from_proper_timezone
all_timestamp_attributes_in_model.each do |column|
if !attribute_present?(column)
_write_attribute(column, current_time)
end
end
end
super
end
all_timestamp_attributes_in_model
をeachで回して、該当するカラムを_write_attribute
メソッドで現在日時に更新している。
all_timestamp_attributes_in_model
はtimestamp_attributes_for_create_in_model
とtimestamp_attributes_for_update
を足したものなので、created_at、created_on、updated_at、updated_on
のどれかがテーブルにあれば更新する。
def all_timestamp_attributes_in_model
timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
end
ちなみに、atだとdatetime、onだとdateのイメージです。
updateの時
def _update_record(*args, touch: true, **options)
if touch && should_record_timestamps?
current_time = current_time_from_proper_timezone
timestamp_attributes_for_update_in_model.each do |column|
next if will_save_change_to_attribute?(column)
_write_attribute(column, current_time)
end
end
super(*args)
end
update時はcreateの時と異なりtimestamp_attributes_for_create_in_model
のみをeachで回して、現在日時に更新してます。
timestamp_attributes_for_create_in_model
はupdated_at
またはupdated_on
が該当するものを抽出しています。
他のメソッドについてもみてみた
- max_updated_column_timestampメソッド
cache_keyを作るために使用している模様
def cache_key(*timestamp_names)
if new_record?
"#{model_name.cache_key}/new"
else
if cache_version && timestamp_names.none?
"#{model_name.cache_key}/#{id}"
else
timestamp = if timestamp_names.any?
ActiveSupport::Deprecation.warn(<<-MSG.squish)
Specifying a timestamp name for #cache_key has been deprecated in favor of
the explicit #cache_version method that can be overwritten.
MSG
max_updated_column_timestamp(timestamp_names)
else
max_updated_column_timestamp
end
if timestamp
timestamp = timestamp.utc.to_s(cache_timestamp_format)
"#{model_name.cache_key}/#{id}-#{timestamp}"
else
"#{model_name.cache_key}/#{id}"
end
end
end
end
- clear_timestamp_attributesメソッド
initialize_dupで使用(initialize_dupはdupした時に呼ばれる)
所感
created_on
、updated_on
を使うと便利になるケースが思い浮かびませんでした。何かこういうPJTで使ったよーみたいなのがあると、是非教えてください。