提交 210ecaec 编写于 作者: J Jeremy Kemper

validates_uniqueness_of behaves well with single-table inheritance. Closes #3833.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7787 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 e7b80cbb
*SVN* *SVN*
* validates_uniqueness_of behaves well with single-table inheritance. #3833 [Gabriel Gironda, rramdas, François Beausoleil, Josh Peek, Tarmo Tänav]
* Raise ProtectedAttributeAssignmentError in development and test environments when mass-assigning to an attr_protected attribute. #9802 [Henrik N] * Raise ProtectedAttributeAssignmentError in development and test environments when mass-assigning to an attr_protected attribute. #9802 [Henrik N]
* Speedup database date/time parsing. [Jeremy Kemper, Tarmo Tänav] * Speedup database date/time parsing. [Jeremy Kemper, Tarmo Tänav]
...@@ -1786,7 +1788,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing] ...@@ -1786,7 +1788,7 @@ during calendar reform. #7649, #7724 [fedot, Geoff Buesing]
* MySQL: more robust test for nullified result hashes. #3124 [Stefan Kaes] * MySQL: more robust test for nullified result hashes. #3124 [Stefan Kaes]
* Reloading an instance refreshes its aggregations as well as its associations. #3024 [François Beausolei] * Reloading an instance refreshes its aggregations as well as its associations. #3024 [François Beausoleil]
* Fixed that using :include together with :conditions array in Base.find would cause NoMethodError #2887 [Paul Hammmond] * Fixed that using :include together with :conditions array in Base.find would cause NoMethodError #2887 [Paul Hammmond]
......
...@@ -619,6 +619,7 @@ def validates_uniqueness_of(*attr_names) ...@@ -619,6 +619,7 @@ def validates_uniqueness_of(*attr_names)
condition_sql = "LOWER(#{record.class.table_name}.#{attr_name}) #{attribute_condition(value)}" condition_sql = "LOWER(#{record.class.table_name}.#{attr_name}) #{attribute_condition(value)}"
condition_params = [value.downcase] condition_params = [value.downcase]
end end
if scope = configuration[:scope] if scope = configuration[:scope]
Array(scope).map do |scope_item| Array(scope).map do |scope_item|
scope_value = record.send(scope_item) scope_value = record.send(scope_item)
...@@ -626,11 +627,13 @@ def validates_uniqueness_of(*attr_names) ...@@ -626,11 +627,13 @@ def validates_uniqueness_of(*attr_names)
condition_params << scope_value condition_params << scope_value
end end
end end
unless record.new_record? unless record.new_record?
condition_sql << " AND #{record.class.table_name}.#{record.class.primary_key} <> ?" condition_sql << " AND #{record.class.table_name}.#{record.class.primary_key} <> ?"
condition_params << record.send(:id) condition_params << record.send(:id)
end end
if record.class.find(:first, :conditions => [condition_sql, *condition_params])
if find(:first, :conditions => [condition_sql, *condition_params])
record.errors.add(attr_name, configuration[:message]) record.errors.add(attr_name, configuration[:message])
end end
end end
......
...@@ -21,6 +21,18 @@ class ProtectedPerson < ActiveRecord::Base ...@@ -21,6 +21,18 @@ class ProtectedPerson < ActiveRecord::Base
attr_protected :first_name attr_protected :first_name
end end
class UniqueReply < Reply
validates_uniqueness_of :content, :scope => 'parent_id'
end
class SillyUniqueReply < UniqueReply
end
class Topic < ActiveRecord::Base
has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
end
class ValidationsTest < Test::Unit::TestCase class ValidationsTest < Test::Unit::TestCase
fixtures :topics, :developers fixtures :topics, :developers
...@@ -320,6 +332,21 @@ def test_validate_uniqueness_with_scope ...@@ -320,6 +332,21 @@ def test_validate_uniqueness_with_scope
assert r3.valid?, "Saving r3" assert r3.valid?, "Saving r3"
end end
def test_validate_uniqueness_scoped_to_defining_class
t = Topic.create("title" => "What, me worry?")
r1 = t.unique_replies.create "title" => "r1", "content" => "a barrel of fun"
assert r1.valid?, "Saving r1"
r2 = t.silly_unique_replies.create "title" => "r2", "content" => "a barrel of fun"
assert !r2.valid?, "Saving r2"
# Should succeed as validates_uniqueness_of only applies to
# UniqueReply and it's subclasses
r3 = t.replies.create "title" => "r2", "content" => "a barrel of fun"
assert r3.valid?, "Saving r3"
end
def test_validate_uniqueness_with_scope_array def test_validate_uniqueness_with_scope_array
Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册