lib/serega/validations/initiate/check_modifiers.rb in serega-0.8.0 vs lib/serega/validations/initiate/check_modifiers.rb in serega-0.8.1

- old
+ new

@@ -8,58 +8,75 @@ module Initiate # # Modifiers validation # class CheckModifiers - class << self - # Validates provided fields names are existing attributes - # - # @param serializer_class [Serega] - # @param fields [Hash] validated fields - # - # @raise [Serega::AttributeNotExist] when modifier not exist as attribute - # - # @return [void] - # - def call(serializer_class, fields) - return unless fields + # + # Validates provided fields names are existing attributes + # + # @param serializer_class [Serega] + # @param only [Hash, nil] `only` modifier + # @param with [Hash, nil] `with` modifier + # @param except [Hash, nil] `except` modifier + # + # @raise [Serega::AttributeNotExist] when some checked modifier has not existing attribute + # + # @return [void] + # + def call(serializer_class, only, with, except) + validate(serializer_class, only) if only + validate(serializer_class, with) if with + validate(serializer_class, except) if except - validate(serializer_class, fields, []) - end + raise_errors if any_error? + end - private + private - def validate(serializer_class, fields, prev_names) - fields.each do |name, nested_fields| - attribute = serializer_class.attributes[name] + def validate(serializer_class, fields) + fields.each do |name, nested_fields| + attribute = serializer_class && serializer_class.attributes[name] - raise_error(name, prev_names) unless attribute - next if nested_fields.empty? + # Save error when no attribute with checked name exists + unless attribute + save_error(name) + next + end - raise_nested_error(name, prev_names, nested_fields) unless attribute.relation? - nested_serializer = attribute.serializer - validate(nested_serializer, nested_fields, prev_names + [name]) + # Return when attribute has no nested fields + next if nested_fields.empty? + + with_parent_name(name) do + validate(attribute.serializer, nested_fields) end end + end - def raise_error(name, prev_names) - field_name = field_name(name, prev_names) + def parents_names + @parents_names ||= [] + end - raise Serega::AttributeNotExist, "Attribute #{field_name} not exists" - end + def with_parent_name(name) + parents_names << name + yield + parents_names.pop + end - def raise_nested_error(name, prev_names, nested_fields) - field_name = field_name(name, prev_names) - first_nested = nested_fields.keys.first + def error_attributes + @error_attributes ||= [] + end - raise Serega::AttributeNotExist, "Attribute #{field_name} has no :serializer option specified to add nested '#{first_nested}' attribute" - end + def save_error(name) + full_attribute_name = [*parents_names, name].join(".") + error_attributes << full_attribute_name + end - def field_name(name, prev_names) - res = "'#{name}'" - res += " ('#{prev_names.join(".")}.#{name}')" if prev_names.any? - res - end + def raise_errors + raise Serega::AttributeNotExist, "Not existing attributes: #{error_attributes.join(", ")}" + end + + def any_error? + defined?(@error_attributes) end end end end end