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
|
# 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)
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)
end
# rubocop:disable Metrics/AbcSize
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
end
end
end
|