/
validations.rb
59 lines (46 loc) · 1.71 KB
/
validations.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module Neo4j
module ActiveNode
# This mixin replace the original save method and performs validation before the save.
module Validations
extend ActiveSupport::Concern
include Neo4j::Shared::Validations
# @return [Boolean] true if valid
def valid?(context = nil)
context ||= (new_record? ? :create : :update)
super(context)
errors.empty?
end
module ClassMethods
def validates_uniqueness_of(*attr_names)
validates_with UniquenessValidator, _merge_attributes(attr_names)
end
end
class UniquenessValidator < ::ActiveModel::EachValidator
def initialize(options)
super(options.reverse_merge(case_sensitive: true))
end
def validate_each(record, attribute, value)
return unless found(record, attribute, value).exists?
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(value: value))
end
def found(record, attribute, value)
conditions = scope_conditions(record)
# TODO: Added as find(:name => nil) throws error
value = '' if value.nil?
conditions[attribute] = options[:case_sensitive] ? value : /#{Regexp.escape(value.to_s)}/i
found = record.class.as(:result).where(conditions)
found = found.where_not(neo_id: record.neo_id) if record._persisted_obj
found
end
def message(instance)
super || 'has already been taken'
end
def scope_conditions(instance)
Array(options[:scope] || []).inject({}) do |conditions, key|
conditions.merge(key => instance[key])
end
end
end
end
end
end