module Forester::Validators
Public Instance Methods
validate_uniqueness_of_field(field, options = {})
click to toggle source
# 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 = {})
click to toggle source
# 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 = {})
click to toggle source
# 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
Private Instance Methods
add_failure(failures, key, subkey, value)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 119 def add_failure(failures, key, subkey, value) failures[key][subkey] << value end
add_failure_if_new(failures, key, subkey, value)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 115 def add_failure_if_new(failures, key, subkey, value) add_failure(failures, key, subkey, value) unless failures[key][subkey].include?(value) end
all_have?(field, nodes)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 92 def all_have?(field, nodes) all_have_all?([field], nodes) end
all_have_all?(fields, nodes)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 96 def all_have_all?(fields, nodes) nodes.all? { |n| fields.all? { |f| n.has_field?(f) } } end
default_validator_options()
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 83 def default_validator_options { first_failure_only: false, within_subtrees_of_depth: 0, among_siblings_of_depth: :not_siblings, as_failure: ->(node) { node } } end
prepare_hash(hash, key, subkey)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 110 def prepare_hash(hash, key, subkey) hash[key] = {} unless hash.key?(key) hash[key][subkey] = [] unless hash[key].key?(subkey) end
result(failures)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 123 def result(failures) { is_valid: failures.empty?, repeated: failures.each_with_object({}) { |(k,v), h| h[k] = v.keys }, failures: failures } end
same_values?(field, nodes)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 100 def same_values?(field, nodes) same_values_for_all?([field], nodes) end
same_values_for_all?(fields, nodes)
click to toggle source
# File lib/forester/tree_node_ext/validators.rb, line 104 def same_values_for_all?(fields, nodes) fields .map { |f| nodes.map { |n| n.get(f) } } .all? { |vs| vs.uniq.length <= 1 } end