Class: CouchRest::Model::Validations::UniquenessValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/couchrest/model/validations/uniqueness.rb

Overview

Validates if a field is unique

Constant Summary collapse

SETUP_DEPRECATED =
ActiveModel.respond_to?(:version) && ActiveModel.version >= Gem::Version.new('4.1')

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ UniquenessValidator

Returns a new instance of UniquenessValidator.


15
16
17
18
# File 'lib/couchrest/model/validations/uniqueness.rb', line 15

def initialize(options = {})
  super
  setup_uniqueness_validation(options[:class]) if options[:class]
end

Instance Method Details

#setup_uniqueness_validation(model) ⇒ Object Also known as: setup

Ensure we have a class available so we can check for a usable view or add one if necessary.


22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/couchrest/model/validations/uniqueness.rb', line 22

def setup_uniqueness_validation(model)
  @model = model
  if options[:view].blank?
    attributes.each do |attribute|
      opts = merge_view_options(attribute)

      unless model.respond_to?(opts[:view_name])
        model.design do
          view opts[:view_name], :allow_nil => true
        end
      end
    end
  end
end

#validate_each(document, attribute, value) ⇒ Object


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/couchrest/model/validations/uniqueness.rb', line 40

def validate_each(document, attribute, value)
  opts = merge_view_options(attribute)

  values = opts[:keys].map{|k| document.send(k)}
  values = values.first if values.length == 1

  model = (document.respond_to?(:model_proxy) && document.model_proxy ? document.model_proxy : @model)
  # Determine the base of the search
  base = opts[:proxy].nil? ? model : document.instance_eval(opts[:proxy])

  unless base.respond_to?(opts[:view_name])
    raise "View #{document.class.name}.#{opts[:view_name]} does not exist for validation!"
  end

  rows = base.send(opts[:view_name], :key => values, :limit => 2, :include_docs => false).rows
  return if rows.empty?

  unless document.new?
    return if rows.find{|row| row.id == document.id}
  end

  if rows.length > 0
    opts = options.merge(:value => value)
    opts.delete(:scope) # Has meaning with I18n!
    document.errors.add(attribute, :taken, opts)
  end
end