Add option to bubble error messages from associated object

main
Guillaume Dott 2023-06-27 16:53:54 +02:00
parent ba354df619
commit 9fa5ebb212
1 changed files with 30 additions and 5 deletions

View File

@ -2,22 +2,47 @@
module ValidatesAssociatedWithContext module ValidatesAssociatedWithContext
class AssociatedWithContextValidator < ActiveModel::EachValidator # :nodoc: class AssociatedWithContextValidator < ActiveModel::EachValidator # :nodoc:
attr_reader :context, :inherit_context attr_reader :inherit_context, :bubble_messages
def initialize(options) def initialize(options)
@context = options.delete(:context) @context = options.delete(:context)
@inherit_context = options.delete(:inherit_context) @inherit_context = options.delete(:inherit_context)
@bubble_messages = options.delete(:bubble_messages)
super super
end end
def validate_each(record, attribute, value) def context(record)
validation_context = inherit_context ? record.validation_context : context return record.validation_context if inherit_context
if @context.respond_to?(:call)
@context.call record
else
@context
end
end
def validate_each(record, attribute, value)
validation_context = context(record)
if bubble_messages
Array(value).each do |r|
next if valid_object?(r, validation_context)
if r.errors.any?
r.errors.each do |error|
record.errors.add(attribute, error.full_message, **options.merge(value: r))
end
else
record.errors.add(attribute, :invalid, **options.merge(value: r))
end
end
else
if Array(value).reject { |r| valid_object?(r, validation_context) }.any? if Array(value).reject { |r| valid_object?(r, validation_context) }.any?
record.errors.add(attribute, :invalid, **options.merge(value: value)) record.errors.add(attribute, :invalid, **options.merge(value: value))
end end
end end
end
private private
def valid_object?(record, validation_context) def valid_object?(record, validation_context)