class MongoModel::DocumentExtensions::Validations::UniquenessValidator

Public Class Methods

new(options) click to toggle source
Calls superclass method
# File lib/mongomodel/document/validations/uniqueness.rb, line 7
def initialize(options)
  options = options.reverse_merge(:case_sensitive => true)

  ActiveSupport::Deprecation.silence { super }
  setup!(options[:class]) if options[:class] && !@klass
end

Public Instance Methods

setup(klass) click to toggle source
# File lib/mongomodel/document/validations/uniqueness.rb, line 14
def setup(klass)
  setup!(klass)
end
validate_each(record, attribute, value) click to toggle source
# File lib/mongomodel/document/validations/uniqueness.rb, line 18
def validate_each(record, attribute, value)
  finder_class = find_finder_class_for(record)
  unique_scope = finder_class.scoped

  if options[:case_sensitive] || !value.is_a?(String)
    unique_scope = unique_scope.where(attribute => value)
  else
    unique_scope = unique_scope.where("_lowercase_#{attribute}" => value.downcase)
  end

  Array.wrap(options[:scope]).each do |scope|
    unique_scope = unique_scope.where(scope => record.send(scope))
  end

  unique_scope = unique_scope.where(:id.ne => record.id) unless record.new_record?

  if unique_scope.any?
    record.errors.add(attribute, :taken, :message => options[:message], :value => value)
  end
end

Private Instance Methods

setup!(klass) click to toggle source
# File lib/mongomodel/document/validations/uniqueness.rb, line 40
def setup!(klass)
  @klass = klass

  unless options[:index] == false
    # Create unique indexes to deal with race condition
    attributes.each do |attr_name|
      if options[:case_sensitive]
        klass.index *[attr_name] + Array.wrap(options[:scope]) << { :unique => true }
      else
        lowercase_key = "_lowercase_#{attr_name}"
        klass.before_save { attributes[lowercase_key] = send(attr_name).downcase }
        klass.index *[lowercase_key] + Array.wrap(options[:scope]) << { :unique => true }
      end
    end
  end
end