Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@kizuna0224

意外と知らないTimestamp

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で使ったよーみたいなのがあると、是非教えてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?