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



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

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

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



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

def validate_uniqueness_of_fields(fields, options = {})
  options = default_validator_options.merge(options)

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

  nodes_of_depth(options[:within_subtrees_of_depth]).each do |subtree|
    visited_nodes = []
    nodes_to_visit =
      if options[:among_siblings_of_depth] == :not_siblings
        subtree.each_node
      else
        nodes_of_depth(options[:among_siblings_of_depth])
      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

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



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/forester/tree_node_ext/validators.rb', line 45

def validate_uniqueness_of_fields_combination(fields, options = {})
  options = default_validator_options.merge(options)

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

  nodes_of_depth(options[:within_subtrees_of_depth]).each do |subtree|
    visited_nodes = []
    nodes_to_visit =
      if options[:among_siblings_of_depth] == :not_siblings
        subtree.each_node
      else
        nodes_of_depth(options[:among_siblings_of_depth])
      end

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

        if same_values_for_all?(fields, [vn, node])
          k = fields.map { |f| vn.get(f) } # repeated combination of values

          prepare_hash(failures, fields, k)

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

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

  result(failures)
end