diff options
author | Godfrey Chan <godfreykfc@gmail.com> | 2014-04-07 18:52:21 -0700 |
---|---|---|
committer | Godfrey Chan <godfreykfc@gmail.com> | 2014-04-07 18:52:21 -0700 |
commit | a5664fe27b1797983537c0764003e618bd3d2801 (patch) | |
tree | dd10cf4cf3f4b627b03dfe07e2c0eda197eb466c | |
parent | 3f5eb59f7a48aa5c08efb8db6cb41cd395c990af (diff) | |
download | rails-a5664fe27b1797983537c0764003e618bd3d2801.tar.gz rails-a5664fe27b1797983537c0764003e618bd3d2801.tar.bz2 rails-a5664fe27b1797983537c0764003e618bd3d2801.zip |
Follow up to bbe7fe41 to fix enum leakage across classes.
The original attempt didn't really fix the problem and wasn't testing the
problematic area. This commit corrected those issues in the original commit.
Also removed the private `enum_mapping_for` method. As `defined_enums` is now a
method, this method doesn't provide much value anymore.
-rw-r--r-- | activerecord/lib/active_record/enum.rb | 9 | ||||
-rw-r--r-- | activerecord/lib/active_record/validations/uniqueness.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/enum_test.rb | 35 |
3 files changed, 35 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb index 167f8b7a49..6e0d19ad31 100644 --- a/activerecord/lib/active_record/enum.rb +++ b/activerecord/lib/active_record/enum.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/deep_dup' + module ActiveRecord # Declare an enum attribute where the values map to integers in the database, # but can be queried by name. Example: @@ -70,8 +72,9 @@ module ActiveRecord base.defined_enums = {} end - def enum_mapping_for(attr_name) # :nodoc: - defined_enums[attr_name.to_s] + def inherited(base) + base.defined_enums = defined_enums.deep_dup + super end def enum(definitions) @@ -136,7 +139,7 @@ module ActiveRecord mod = Module.new do private def save_changed_attribute(attr_name, value) - if (mapping = self.class.enum_mapping_for(attr_name)) + if (mapping = self.class.defined_enums[attr_name]) if attribute_changed?(attr_name) old = changed_attributes[attr_name] diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 71c71cb4b1..ee080451a9 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -93,7 +93,7 @@ module ActiveRecord end def map_enum_attribute(klass, attribute, value) - mapping = klass.enum_mapping_for(attribute.to_s) + mapping = klass.defined_enums[attribute.to_s] value = mapping[value] if value && mapping value end diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 5157c272ca..3b2f0dfe07 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -252,17 +252,38 @@ class EnumTest < ActiveRecord::TestCase end test "enums are distinct per class" do - Plane = Class.new(ActiveRecord::Base) do - enum status: [:grounded, :operational] + klass1 = Class.new(ActiveRecord::Base) do + self.table_name = "books" + enum status: [:proposed, :written] + end + + klass2 = Class.new(ActiveRecord::Base) do + self.table_name = "books" + enum status: [:drafted, :uploaded] end - assert_equal({ "proposed" => 0, "written" => 1, "published" => 2 }, Book.statuses) - assert_equal({ "grounded" => 0, "operational" => 1 }, Plane.statuses) + + book1 = klass1.proposed.create! + book1.status = :written + assert_equal ['proposed', 'written'], book1.status_change + + book2 = klass2.drafted.create! + book2.status = :uploaded + assert_equal ['drafted', 'uploaded'], book2.status_change end test "enums are inheritable" do - Encyclopedia = Class.new(Book) do - enum status: [:published, :reprinted] + subklass1 = Class.new(Book) + + subklass2 = Class.new(Book) do + enum status: [:drafted, :uploaded] end - assert_equal({ "published" => 0, "reprinted" => 1 }, Encyclopedia.statuses) + + book1 = subklass1.proposed.create! + book1.status = :written + assert_equal ['proposed', 'written'], book1.status_change + + book2 = subklass2.drafted.create! + book2.status = :uploaded + assert_equal ['drafted', 'uploaded'], book2.status_change end end |