diff options
-rw-r--r-- | activerecord/CHANGELOG.md | 8 | ||||
-rw-r--r-- | activerecord/lib/active_record/validations/uniqueness.rb | 7 | ||||
-rw-r--r-- | activerecord/test/cases/enum_test.rb | 27 |
3 files changed, 42 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 58f680a03f..2845e945db 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* Fixed error with validation with enum fields for records where the + value for any enum attribute is always evaluated as 0 during + uniqueness validation. + + Fixes #14172 + + *Vilius Luneckas* *Ahmed AbouElhamayed* + * `before_add` callbacks are fired before the record is saved on `has_and_belongs_to_many` assocations *and* on `has_many :through` associations. Before this change, `before_add` callbacks would be fired diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 7ebe9dfec0..49b0f73219 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -13,6 +13,7 @@ module ActiveRecord def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) table = finder_class.arel_table + value = map_enum_attribute(finder_class,attribute,value) value = deserialize_attribute(record, attribute, value) relation = build_relation(finder_class, table, attribute, value) @@ -91,6 +92,12 @@ module ActiveRecord value = coder.dump value if value && coder value end + + def map_enum_attribute(klass,attribute,value) + mapping = klass.enum_mapping_for(attribute.to_s) + value = mapping[value] if value && mapping + value + end end module ClassMethods diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 1b95708cb3..f8ebd7caee 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -222,4 +222,31 @@ class EnumTest < ActiveRecord::TestCase end end end + + test "validate uniqueness" do + klass = Class.new(ActiveRecord::Base) do + def self.name; 'Book'; end + enum status: [:proposed, :written] + validates_uniqueness_of :status + end + klass.delete_all + klass.create!(status: "proposed") + book = klass.new(status: "written") + assert book.valid? + book.status = "proposed" + assert_not book.valid? + end + + test "validate inclusion of value in array" do + klass = Class.new(ActiveRecord::Base) do + def self.name; 'Book'; end + enum status: [:proposed, :written] + validates_inclusion_of :status, in: ["written"] + end + klass.delete_all + invalid_book = klass.new(status: "proposed") + assert_not invalid_book.valid? + valid_book = klass.new(status: "written") + assert valid_book.valid? + end end |