LoginSignup
2
1

More than 5 years have passed since last update.

意外と知らないTimestamp

Last updated at Posted at 2018-11-02

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_modeltimestamp_attributes_for_create_in_modeltimestamp_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_modelupdated_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_onupdated_onを使うと便利になるケースが思い浮かびませんでした。何かこういうPJTで使ったよーみたいなのがあると、是非教えてください。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1