diff options
Diffstat (limited to 'activerecord/lib/active_record/timestamp.rb')
-rw-r--r-- | activerecord/lib/active_record/timestamp.rb | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index 5531d12a41..1511c71ffc 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -1,72 +1,83 @@ +require 'active_support/core_ext/class/attribute' + module ActiveRecord # = Active Record Timestamp - # + # # Active Record automatically timestamps create and update operations if the - # table has fields named <tt>created_at/created_on</tt> or + # table has fields named <tt>created_at/created_on</tt> or # <tt>updated_at/updated_on</tt>. # # Timestamping can be turned off by setting: # - # <tt>ActiveRecord::Base.record_timestamps = false</tt> + # config.active_record.record_timestamps = false # # Timestamps are in the local timezone by default but you can use UTC by setting: # - # <tt>ActiveRecord::Base.default_timezone = :utc</tt> + # config.active_record.default_timezone = :utc # # == Time Zone aware attributes # # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code. # - # ActiveRecord::Base.time_zone_aware_attributes = true + # config.active_record.time_zone_aware_attributes = true # # This feature can easily be turned off by assigning value <tt>false</tt> . # - # If your attributes are time zone aware and you desire to skip time zone conversion for certain - # attributes then you can do following: + # If your attributes are time zone aware and you desire to skip time zone conversion to the current Time.zone + # when reading certain attributes then you can do following: # - # Topic.skip_time_zone_conversion_for_attributes = [:written_on] + # class Topic < ActiveRecord::Base + # self.skip_time_zone_conversion_for_attributes = [:written_on] + # end module Timestamp extend ActiveSupport::Concern included do - class_inheritable_accessor :record_timestamps, :instance_writer => false + class_attribute :record_timestamps, :instance_writer => false self.record_timestamps = true end private def create #:nodoc: - if record_timestamps + if self.record_timestamps current_time = current_time_from_proper_timezone - timestamp_attributes_for_create.each do |column| + all_timestamp_attributes.each do |column| write_attribute(column.to_s, current_time) if respond_to?(column) && self.send(column).nil? end - - timestamp_attributes_for_update_in_model.each do |column| - write_attribute(column.to_s, current_time) if self.send(column).nil? - end end super end def update(*args) #:nodoc: - record_update_timestamps if !partial_updates? || changed? + if should_record_timestamps? + current_time = current_time_from_proper_timezone + + timestamp_attributes_for_update_in_model.each do |column| + column = column.to_s + next if attribute_changed?(column) + write_attribute(column, current_time) + end + end super end - def record_update_timestamps #:nodoc: - return unless record_timestamps - current_time = current_time_from_proper_timezone - timestamp_attributes_for_update_in_model.inject({}) do |hash, column| - hash[column.to_s] = write_attribute(column.to_s, current_time) - hash - end + def should_record_timestamps? + self.record_timestamps && (!partial_updates? || changed? || (attributes.keys & self.class.serialized_attributes.keys).present?) + end + + def timestamp_attributes_for_create_in_model + timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) } + end + + def timestamp_attributes_for_update_in_model + timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) } end - def timestamp_attributes_for_update_in_model #:nodoc: - timestamp_attributes_for_update.select { |elem| respond_to?(elem) } + def all_timestamp_attributes_in_model + timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model end def timestamp_attributes_for_update #:nodoc: @@ -78,9 +89,9 @@ module ActiveRecord end def all_timestamp_attributes #:nodoc: - timestamp_attributes_for_update + timestamp_attributes_for_create + timestamp_attributes_for_create + timestamp_attributes_for_update end - + def current_time_from_proper_timezone #:nodoc: self.class.default_timezone == :utc ? Time.now.utc : Time.now end |