lib/easy_params/base.rb in easy_params-0.2.1 vs lib/easy_params/base.rb in easy_params-0.3.0

- old
+ new

@@ -1,6 +1,9 @@ +# frozen_string_literal: true + module EasyParams + # Implements validations logic and nesting structures class Base < Dry::Struct include ActiveModel::Validations transform_keys(&:to_sym) @@ -14,31 +17,50 @@ validate do validate_nested end + private + def validate_nested - run_nested_validations = proc do |attr_name, value, array_index, error_key_prefix| + attributes.each(&run_nested_validations) + end + + def run_nested_validations + proc do |attr_name, value, array_index, error_key_prefix| case value when Array value.each.with_index do |element, i| run_nested_validations[attr_name, element, i, error_key_prefix] end when self.class.struct - if value.invalid? - error_key_components = [error_key_prefix, attr_name, array_index] - attr_error_key_prefix = error_key_components.compact.join('/') - value.errors.each do |error_key, error_message| - errors.add("#{attr_error_key_prefix}/#{error_key}", error_message) - end - end - value.attributes.each do |nested_attr_name, nested_value| - run_nested_validations[nested_attr_name, nested_value, nil, attr_error_key_prefix] - end - else - # NOOP + handle_struct_validation(value, error_key_prefix, attr_name, array_index) end end - attributes.each(&run_nested_validations) + end + + def handle_struct_validation(value, error_key_prefix, attr_name, array_index) + if value.invalid? + error_key_components = [error_key_prefix, attr_name, array_index] + attr_error_key_prefix = error_key_components.compact.join('/') + add_errors_on_top_level(value, attr_error_key_prefix) + end + value.attributes.each do |nested_attr_name, nested_value| + run_nested_validations[nested_attr_name, nested_value, nil, attr_error_key_prefix] + end + end + + if defined? ActiveModel::Error + def add_errors_on_top_level(value, attr_error_key_prefix) + value.errors.each do |error| + next unless error.options[:message] + + errors.add("#{attr_error_key_prefix}/#{error.attribute}", error.options[:message]) + end + end + else + def add_errors_on_top_level(value, attr_error_key_prefix) + value.errors.each { |key, message| errors.add("#{attr_error_key_prefix}/#{key}", message) } + end end end end