Module: Forester::Validators

Included in:
TreeNode
Defined in:
lib/forester/tree_node_ext/validators.rb

Instance Method Summary collapse

Instance Method Details

#validate_uniqueness_of_field(field, options = {}) ⇒ Object



4
5
6
# File 'lib/forester/tree_node_ext/validators.rb', line 4

def validate_uniqueness_of_field(field, options = {})
  validate_uniqueness_of_fields([field], options)
end

#validate_uniqueness_of_fields(fields, options = {}) ⇒ Object



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
# File 'lib/forester/tree_node_ext/validators.rb', line 8

def validate_uniqueness_of_fields(fields, options = {})
  default_options = {
    combination:              false,
    first_failure_only:       false,
    within_subtrees_of_level: 0,
    among_siblings_of_level:  :not_siblings,
    field_for_failures:       :name,
    as_failure: ->(node) { node.get(options[:field_for_failures]) }
  }
  options = default_options.merge(options)

  return of_combination_of_fields(fields, options) if options[:combination]

  failures = Hash.new(Hash.new([]))

  nodes_of_level(options[:within_subtrees_of_level]).each do |subtree|
    visited_nodes = []
    nodes_to_visit =
      if options[:among_siblings_of_level] == :not_siblings
        subtree.each_node
      else
        nodes_of_level(options[:among_siblings_of_level])
      end

    nodes_to_visit.each  do |node|
      visited_nodes.each do |vn|
        fields.each      do |field|
          next unless all_have?(field, [vn, node])

          if same_values?(field, [vn, node])
            k = vn.get(field) # repeated value

            prepare_hash(failures, field, k)

            add_failure_if_new(failures, field, k, options[:as_failure].call(vn))
            add_failure(       failures, field, k, options[:as_failure].call(node))

            return result(failures) if options[:first_failure_only]
          end
        end
      end
      visited_nodes << node
    end
  end

  result(failures)
end