Method: Sequel::Plugins::ValidationClassMethods::ClassMethods#validates_uniqueness_of

Defined in:
lib/sequel/plugins/validation_class_methods.rb

#validates_uniqueness_of(*atts) ⇒ Object

Validates only if the fields in the model (specified by atts) are unique in the database. Pass an array of fields instead of multiple fields to specify that the combination of fields must be unique, instead of that each field should have a unique value.

This means that the code:

validates_uniqueness_of([:column1, :column2])

validates the grouping of column1 and column2 while

validates_uniqueness_of(:column1, :column2)

validates them separately.

You should also add a unique index in the database, as this suffers from a fairly obvious race condition.

Possible Options:

:message

The message to use (default: ‘is already taken’)



389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'lib/sequel/plugins/validation_class_methods.rb', line 389

def validates_uniqueness_of(*atts)
  opts = {
    :message => 'is already taken',
    :tag => :uniqueness,
  }.merge!(extract_options!(atts))
    
  reflect_validation(:uniqueness, opts, atts)
  atts << opts
  validates_each(*atts) do |o, a, v|
    error_field = a
    a = Array(a)
    v = Array(v)
    next if v.empty? || !v.all?
    ds = o.class.where(a.zip(v))
    num_dups = ds.count
    allow = if num_dups == 0
      # No unique value in the database
      true
    elsif num_dups > 1
      # Multiple "unique" values in the database!!
      # Someone didn't add a unique index
      false
    elsif o.new?
      # New record, but unique value already exists in the database
      false
    elsif ds.first === o
      # Unique value exists in database, but for the same record, so the update won't cause a duplicate record
      true
    else
      false
    end
    o.errors.add(error_field, opts[:message]) unless allow
  end
end