Class: NoBrainer::Document::Validation::Uniqueness::UniquenessValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/no_brainer/document/validation/uniqueness.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ UniquenessValidator

Returns a new instance of UniquenessValidator.



59
60
61
62
63
64
65
66
67
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 59

def initialize(options={})
  super
  self.model = options[:class]
  self.scope = [*options[:scope]].map(&:to_sym)

  model.subclass_tree.each do |subclass|
    subclass.unique_validators << self
  end
end

Instance Attribute Details

#modelObject

Returns the value of attribute model.



57
58
59
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 57

def model
  @model
end

#scopeObject

Returns the value of attribute scope.



57
58
59
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 57

def scope
  @scope
end

Instance Method Details

#apply_scopes(criteria, doc) ⇒ Object



85
86
87
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 85

def apply_scopes(criteria, doc)
  criteria.where(scope.map { |k| {k => doc._read_attribute(k)} })
end

#exclude_doc(criteria, doc) ⇒ Object



89
90
91
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 89

def exclude_doc(criteria, doc)
  criteria.where(doc.class.pk_name.not => doc.pk_value)
end

#should_validate_field?(doc, field) ⇒ Boolean

Returns:



69
70
71
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 69

def should_validate_field?(doc, field)
  doc.new_record? || (scope + [field]).any? { |f| doc.__send__("#{f}_changed?") }
end

#validate_each(doc, attr, value) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/no_brainer/document/validation/uniqueness.rb', line 73

def validate_each(doc, attr, value)
  criteria = self.model.unscoped.where(attr => value)
  criteria = apply_scopes(criteria, doc)
  criteria = exclude_doc(criteria, doc) if doc.persisted?
  doc.errors.add(attr, :taken, **options.except(:scope).merge(:value => value)) unless criteria.empty?
rescue NoBrainer::Error::InvalidType
  # We can't run the uniqueness validator: where() won't accept bad types
  # and we have some values that don't have the right type.
  # Note that it's fine to not add errors because the type validations will
  # prevent the document from being saved.
end