提交 070c9984 编写于 作者: R Raimonds Simanovskis

Do not use SQL LIKE operator for case insensitive uniqueness validation

It can result in wrong results if values contain special % or _ characters. It is safer to use SQL LOWER function and compare for equality.
上级 12427c8d
......@@ -56,8 +56,9 @@ def build_relation(klass, table, attribute, value) #:nodoc:
column = klass.columns_hash[attribute.to_s]
value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text?
if !options[:case_sensitive] && column.text?
relation = table[attribute].matches(value)
if !options[:case_sensitive] && value && column.text?
# will use SQL LOWER function before comparison
relation = table[attribute].lower.eq(table.lower(value))
else
value = klass.connection.case_sensitive_modifier(value)
relation = table[attribute].eq(value)
......
......@@ -162,6 +162,32 @@ def test_validate_case_insensitive_uniqueness
end
end
def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars
Topic.validates_uniqueness_of(:title, :case_sensitive => true)
t = Topic.new("title" => "I'm unique!")
assert t.save, "Should save t as unique"
t2 = Topic.new("title" => "I'm %")
assert t2.save, "Should save t2 as unique"
t3 = Topic.new("title" => "I'm uniqu_!")
assert t3.save, "Should save t3 as unique"
end
def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars
Topic.validates_uniqueness_of(:title, :case_sensitive => false)
t = Topic.new("title" => "I'm unique!")
assert t.save, "Should save t as unique"
t2 = Topic.new("title" => "I'm %")
assert t2.save, "Should save t2 as unique"
t3 = Topic.new("title" => "I'm uniqu_!")
assert t3.save, "Should save t3 as unique"
end
def test_validate_case_sensitive_uniqueness
Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册