forked from bootstrap-ruby/bootstrap_form
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidation.rb
More file actions
93 lines (72 loc) · 2.98 KB
/
validation.rb
File metadata and controls
93 lines (72 loc) · 2.98 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
module BootstrapForm
module Components
module Validation
extend ActiveSupport::Concern
private
def error?(name)
name && object.respond_to?(:errors) && (object.errors[name].any? || association_error?(name))
end
def association_error?(name)
object.class.try(:reflections)&.any? do |association_name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == name.to_s
object.errors[association_name].any?
end
end
def required_attribute?(obj, attribute)
return false unless obj && attribute
target = obj.instance_of?(Class) ? obj : obj.class
return false unless target.respond_to? :validators_on
presence_validators?(target, obj, attribute) || required_association?(target, obj, attribute)
end
def required_association?(target, object, attribute)
target.try(:reflections)&.any? do |name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == attribute.to_s
presence_validators?(target, object, name)
end
end
def presence_validators?(target, object, attribute)
target.validators_on(attribute).select { |v| presence_validator?(v.class) }.any? do |validator|
if_option = validator.options[:if]
unless_opt = validator.options[:unless]
(!if_option || call_with_self(object, if_option)) && (!unless_opt || !call_with_self(object, unless_opt))
end
end
def call_with_self(object, proc)
proc = object.method(proc) if proc.is_a? Symbol
object.instance_exec(*[(object if proc.arity >= 1)].compact, &proc)
end
def presence_validator?(validator_class)
validator_class == ActiveModel::Validations::PresenceValidator ||
(defined?(ActiveRecord::Validations::PresenceValidator) &&
validator_class == ActiveRecord::Validations::PresenceValidator)
end
def inline_error?(name)
error?(name) && inline_errors
end
def generate_error(name, id)
return unless inline_error?(name)
help_text = get_error_messages(name)
help_klass = "invalid-feedback"
help_tag = :div
content_tag(help_tag, help_text, class: help_klass, id: aria_feedback_id(id:, name:))
end
def get_error_messages(name)
object.class.try(:reflections)&.each do |association_name, a|
next unless a.is_a?(ActiveRecord::Reflection::BelongsToReflection)
next unless a.foreign_key == name.to_s
object.errors[association_name].each do |error|
object.errors.add(name, error)
end
end
safe_join(object.errors[name], ", ")
end
# rubocop:enable Metrics/AbcSize
def aria_feedback_id(name:, id: nil)
id.present? ? "#{id}_feedback" : field_id(name, :feedback)
end
end
end
end