Method: ActiveRecord::Validations::ClassMethods#validates_uniqueness_of

Defined in:
lib/active_record/validations.rb

#validates_uniqueness_of(*attr_names) ⇒ Object

Validates whether the value of the specified attributes are unique across the system. Useful for making sure that only one user can be named “davidhh”.

class Person < ActiveRecord::Base
  validates_uniqueness_of :user_name, :scope => "account_id"
end

When the record is created, a check is performed to make sure that no record exist in the database with the given value for the specified attribute (that maps to a column). When the record is updated, the same check is made but disregarding the record itself.

Configuration options:

  • message - Specifies a custom error message (default is: “has already been taken”)

  • scope - Ensures that the uniqueness is restricted to a condition of “scope = record.scope”



410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/active_record/validations.rb', line 410

def validates_uniqueness_of(*attr_names)
  configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken] }
  configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)

  if scope = configuration[:scope]
    validates_each(attr_names,configuration) do |record, attr_name, value|
      record.errors.add(attr_name, configuration[:message]) if record.class.find_first(record.new_record? ? ["#{attr_name} = ? AND #{scope} = ?", record.send(attr_name), record.send(scope)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ? AND #{scope} = ?", record.send(attr_name), record.send(:id), record.send(scope)])
    end
  else
    validates_each(attr_names,configuration) do |record, attr_name, value|
      record.errors.add(attr_name, configuration[:message]) if record.class.find_first(record.new_record? ? ["#{attr_name} = ?", record.send(attr_name)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ?", record.send(attr_name), record.send(:id) ] )
    end
  end
end