class ActiveRecord::Validations::GlobalizedUniquenessValidator
Public Class Methods
new(options)
click to toggle source
Calls superclass method
# File lib/active_record/validations/globalized_uniqueness.rb, line 6 def initialize(options) super(options.reverse_merge(:case_sensitive => true)) end
Public Instance Methods
setup(klass)
click to toggle source
Unfortunately, we have to tie Uniqueness validators to a class.
# File lib/active_record/validations/globalized_uniqueness.rb, line 11 def setup(klass) @klass = klass end
validate_each(record, attribute, value)
click to toggle source
# File lib/active_record/validations/globalized_uniqueness.rb, line 15 def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) table = finder_class.arel_table coder = record.class.serialized_attributes[attribute.to_s] # FIXME add/test support for serialized attributes with globalize3 # determine table / attr_column_class respecting globalize3 translations globalized_column_class = find_globalized_column_class_for(record, attribute) globalized = globalized_column_class.present? if globalized attr_column_class = globalized_column_class table = attr_column_class.arel_table else attr_column_class = finder_class end if value && coder value = coder.dump value end # build relation respecting globalize3 translations relation = build_relation(attr_column_class, table, attribute, value) relation = relation.and(finder_class.arel_table[finder_class.primary_key.to_sym].not_eq(record.send(:id))) if record.persisted? Array.wrap(options[:scope]).each do |scope_item| if globalized && ([:locale] | record.class.translated_attribute_names).include?(scope_item) # handle globalize3 translated attribute scopes and :locale scope scope_value = if scope_item == :locale Globalize.locale.to_s else record.read_attribute(scope_item) end relation = relation.and(table[scope_item].eq(scope_value)) else scope_value = record.read_attribute(scope_item) relation = relation.and(finder_class.arel_table[scope_item].eq(scope_value)) end end # finalize building & execute query (respecting globalize3 translations) scoped = finder_class.unscoped scoped = scoped.joins(:translations) if globalized if scoped.where(relation).exists? record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) end end
Protected Instance Methods
find_globalized_column_class_for(record, attribute)
click to toggle source
If the attribute of the record is globalized, returns the translation class; otherwise, returns nil.
# File lib/active_record/validations/globalized_uniqueness.rb, line 80 def find_globalized_column_class_for(record, attribute) class_hierarchy = [record.class] while class_hierarchy.first != @klass class_hierarchy.insert(0, class_hierarchy.first.superclass) end klass = class_hierarchy.detect { |klass| !klass.abstract_class? && klass.respond_to?(:translation_class) } if klass && record.class.translated_attribute_names.include?(attribute) klass.translation_class else nil end end