Permalink
Browse files

Fix a bug affecting validations of enum attributes

This fixes a bug where any enum attribute of a model
would be evaluated always as 0 when calling the
database on validations.

This fix converts the value of the enum attribute
to its integer value rather than the string before
building the relation as the bug occured when the
string finally gets converted to integer using
string.to_i which converts it to 0.

[Vilius Luneckas, Ahmed AbouElhamayed]
  • Loading branch information...
1 parent 14e697c commit 6e53d92498ada27cea6c7bae85708fcf5579223c @Alwahsh Alwahsh committed Feb 26, 2014
View
8 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
View
7 activerecord/lib/active_record/validations/uniqueness.rb
@@ -13,6 +13,7 @@ def initialize(options)
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 @@ def deserialize_attribute(record, attribute, value)
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
View
27 activerecord/test/cases/enum_test.rb
@@ -222,4 +222,31 @@ def written!
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

0 comments on commit 6e53d92

Please sign in to comment.