aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activemodel/lib/active_model/dirty.rb4
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb12
-rw-r--r--activerecord/lib/active_record/attribute_mutation_tracker.rb29
3 files changed, 41 insertions, 4 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index 0169c20e0b..0ab8df42f5 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -203,7 +203,7 @@ module ActiveModel
# Returns +true+ if attr_name were changed before the model was saved,
# +false+ otherwise.
def previous_changes_include?(attr_name)
- @previously_changed.include?(attr_name)
+ previous_changes.include?(attr_name)
end
# Removes current changes and makes them accessible through +previous_changes+.
@@ -225,7 +225,7 @@ module ActiveModel
# Handles <tt>*_previous_change</tt> for +method_missing+.
def attribute_previous_change(attr)
- @previously_changed[attr] if attribute_previously_changed?(attr)
+ previous_changes[attr] if attribute_previously_changed?(attr)
end
# Handles <tt>*_will_change!</tt> for +method_missing+.
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index a439683185..24f0ccb239 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -51,12 +51,12 @@ module ActiveRecord
end
def changes_applied
- super
+ @previous_mutation_tracker = @mutation_tracker
store_original_attributes
end
def clear_changes_information
- super
+ @previous_mutation_tracker = nil
store_original_attributes
end
@@ -89,6 +89,10 @@ module ActiveRecord
end
end
+ def previous_changes
+ previous_mutation_tracker.changes
+ end
+
def attribute_changed_in_place?(attr_name)
@mutation_tracker.changed_in_place?(attr_name)
end
@@ -119,6 +123,10 @@ module ActiveRecord
@mutation_tracker = @mutation_tracker.now_tracking(@attributes)
end
+ def previous_mutation_tracker
+ @previous_mutation_tracker ||= NullMutationTracker.new
+ end
+
def cache_changed_attributes
@cached_changed_attributes = changed_attributes
yield
diff --git a/activerecord/lib/active_record/attribute_mutation_tracker.rb b/activerecord/lib/active_record/attribute_mutation_tracker.rb
index e4be5c5524..168794fcb4 100644
--- a/activerecord/lib/active_record/attribute_mutation_tracker.rb
+++ b/activerecord/lib/active_record/attribute_mutation_tracker.rb
@@ -13,6 +13,14 @@ module ActiveRecord
end
end
+ def changes
+ attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
+ if changed?(attr_name)
+ result[attr_name] = [original_attributes.fetch_value(attr_name), attributes.fetch_value(attr_name)]
+ end
+ end
+ end
+
def changed?(attr_name)
attr_name = attr_name.to_s
modified?(attr_name) || changed_in_place?(attr_name)
@@ -52,4 +60,25 @@ module ActiveRecord
end
end
end
+
+ class NullMutationTracker
+ def changed_values
+ {}
+ end
+
+ def changes
+ {}
+ end
+
+ def changed?(*)
+ false
+ end
+
+ def changed_in_place?(*)
+ false
+ end
+
+ def forget_change(*)
+ end
+ end
end