aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations/uniqueness.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/validations/uniqueness.rb')
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb25
1 files changed, 18 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 2e2ea8c42b..3a741ba600 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/array/wrap'
-
module ActiveRecord
module Validations
class UniquenessValidator < ActiveModel::EachValidator
@@ -25,8 +23,13 @@ module ActiveRecord
relation = build_relation(finder_class, table, attribute, value)
relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.send(:id))) if record.persisted?
- Array.wrap(options[:scope]).each do |scope_item|
+ Array(options[:scope]).each do |scope_item|
scope_value = record.send(scope_item)
+ reflection = record.class.reflect_on_association(scope_item)
+ if reflection
+ scope_value = record.send(reflection.foreign_key)
+ scope_item = reflection.foreign_key
+ end
relation = relation.and(table[scope_item].eq(scope_value))
end
@@ -53,14 +56,22 @@ module ActiveRecord
end
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?
+ reflection = klass.reflect_on_association(attribute)
+ column = nil
+ if(reflection)
+ column = klass.columns_hash[reflection.foreign_key]
+ attribute = reflection.foreign_key
+ value = value.attributes[reflection.primary_key_column.name]
+ else
+ column = klass.columns_hash[attribute.to_s]
+ end
+ value = column.limit ? value.to_s[0, column.limit] : value.to_s if !value.nil? && column.text?
if !options[:case_sensitive] && value && column.text?
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
relation = klass.connection.case_insensitive_comparison(table, attribute, column, value)
else
- value = klass.connection.case_sensitive_modifier(value)
+ value = klass.connection.case_sensitive_modifier(value) unless value.nil?
relation = table[attribute].eq(value)
end
@@ -81,7 +92,7 @@ module ActiveRecord
#
# class Person < ActiveRecord::Base
# validates_uniqueness_of :user_name, :scope => :account_id
- # end
+ # end
#
# Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once
# per semester for a particular class.