aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2014-01-21 20:37:45 -0200
committerRafael Mendonça França <rafaelmfranca@gmail.com>2014-01-21 20:37:45 -0200
commit9383de42a2cf23cc53052cec2f736864c1c562a1 (patch)
tree19ddfa20500d526311bb48f4a8ae5abffe046963 /activerecord/lib/active_record
parentc6ecfc1668d6e2c69d360ed376b9e3f77ad72e83 (diff)
parent55f6c8c908fea2609cbc8503f8d87460fd1b16b4 (diff)
downloadrails-9383de42a2cf23cc53052cec2f736864c1c562a1.tar.gz
rails-9383de42a2cf23cc53052cec2f736864c1c562a1.tar.bz2
rails-9383de42a2cf23cc53052cec2f736864c1c562a1.zip
Merge pull request #13776 from rails/dirty-enum
Implement the Dirty API with the Enum feature correctly. Conflicts: activerecord/CHANGELOG.md
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb9
-rw-r--r--activerecord/lib/active_record/enum.rb31
2 files changed, 36 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 19e81abba5..68168bb729 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -43,6 +43,12 @@ module ActiveRecord
def write_attribute(attr, value)
attr = attr.to_s
+ save_changed_attribute(attr, value)
+
+ super(attr, value)
+ end
+
+ def save_changed_attribute(attr, value)
# The attribute already has an unsaved change.
if attribute_changed?(attr)
old = changed_attributes[attr]
@@ -51,9 +57,6 @@ module ActiveRecord
old = clone_attribute_value(:read_attribute, attr)
changed_attributes[attr] = old if _field_changed?(attr, old, value)
end
-
- # Carry on.
- super(attr, value)
end
def update_record(*)
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 3deb2d65f8..53dde5e564 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -63,6 +63,12 @@ module ActiveRecord
#
# Conversation.where("status <> ?", Conversation.statuses[:archived])
module Enum
+ DEFINED_ENUMS = {} # :nodoc:
+
+ def enum_mapping_for(attr_name) # :nodoc:
+ DEFINED_ENUMS[attr_name.to_s]
+ end
+
def enum(definitions)
klass = self
definitions.each do |name, values|
@@ -107,6 +113,8 @@ module ActiveRecord
# def active!() update! status: :active end
define_method("#{value}!") { update! name => value }
end
+
+ DEFINED_ENUMS[name.to_s] = enum_values
end
end
end
@@ -114,7 +122,28 @@ module ActiveRecord
private
def _enum_methods_module
@_enum_methods_module ||= begin
- mod = Module.new
+ mod = Module.new do
+ private
+ def save_changed_attribute(attr_name, value)
+ if (mapping = self.class.enum_mapping_for(attr_name))
+ if attribute_changed?(attr_name)
+ old = changed_attributes[attr_name]
+
+ if mapping[old] == value
+ changed_attributes.delete(attr_name)
+ end
+ else
+ old = clone_attribute_value(:read_attribute, attr_name)
+
+ if old != value
+ changed_attributes[attr_name] = mapping.key old
+ end
+ end
+ else
+ super
+ end
+ end
+ end
include mod
mod
end