diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb index eb853f01ee..c6a79acf81 100644 --- a/activemodel/lib/active_model/observing.rb +++ b/activemodel/lib/active_model/observing.rb @@ -1,6 +1,7 @@ require 'singleton' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/module/aliasing' +require 'active_support/core_ext/module/remove_method' require 'active_support/core_ext/string/inflections' module ActiveModel @@ -157,7 +158,7 @@ module ActiveModel def observe(*models) models.flatten! models.collect! { |model| model.respond_to?(:to_sym) ? model.to_s.camelize.constantize : model } - remove_method(:observed_classes) + remove_possible_method(:observed_classes) define_method(:observed_classes) { models } end diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 8d093c81de..828a8b41b6 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -106,15 +106,17 @@ module ActiveRecord # or callbacks. This is especially useful for boolean flags on existing records. def update_attribute(name, value) send("#{name}=", value) - primary_key = self.class.primary_key - h = {name => value} - if should_record_update_timestamps - self.send(:record_update_timestamps) - current_time = current_time_from_proper_timezone - timestamp_attributes_for_update_in_model.each { |column| h.merge!(column => current_time) } + hash = { name => read_attribute(name) } + + if record_update_timestamps + timestamp_attributes_for_update_in_model.each do |column| + hash[column] = read_attribute(column) + end end - self.class.update_all(h, {primary_key => self[primary_key]}) == 1 + @changed_attributes.delete(name.to_s) + primary_key = self.class.primary_key + self.class.update_all(hash, { primary_key => self[primary_key] }) == 1 end # Updates all the attributes from the passed-in Hash and saves the record. diff --git a/activerecord/lib/active_record/timestamp.rb b/activerecord/lib/active_record/timestamp.rb index e6d52744df..1075a60f07 100644 --- a/activerecord/lib/active_record/timestamp.rb +++ b/activerecord/lib/active_record/timestamp.rb @@ -49,8 +49,8 @@ module ActiveRecord write_attribute('created_at', current_time) if respond_to?(:created_at) && created_at.nil? write_attribute('created_on', current_time) if respond_to?(:created_on) && created_on.nil? - timestamp_attributes_for_update.each do |column| - write_attribute(column.to_s, current_time) if respond_to?(column) && self.send(column).nil? + timestamp_attributes_for_update_in_model.each do |column| + write_attribute(column.to_s, current_time) if self.send(column).nil? end end @@ -63,23 +63,17 @@ module ActiveRecord end def record_update_timestamps - if should_record_update_timestamps + if record_timestamps && (!partial_updates? || changed?) current_time = current_time_from_proper_timezone timestamp_attributes_for_update_in_model.each { |column| write_attribute(column.to_s, current_time) } + true + else + false end end - def should_record_update_timestamps - record_timestamps && (!partial_updates? || changed?) - end - - - def timestamp_attributes_for_update #:nodoc: - [:updated_at, :updated_on] - end - def timestamp_attributes_for_update_in_model #:nodoc: - ([:updated_at, :updated_on].inject([]) { |sum, elem| respond_to?(elem) ? sum << elem : sum }) + [:updated_at, :updated_on].select { |elem| respond_to?(elem) } end def current_time_from_proper_timezone #:nodoc: