class Hanami::Action::Params::Errors

Params errors

@since 1.1.0

Public Class Methods

new(errors = {}) click to toggle source

@since 1.1.0 @api private

Calls superclass method
# File lib/hanami/action/params.rb, line 25
def initialize(errors = {})
  super(errors)
end

Public Instance Methods

add(*args) click to toggle source

Add an error to the param validations

This has a semantic similar to `Hash#dig` where you use a set of keys to get a nested value, here you use a set of keys to set a nested value.

@param args [Array<Symbol, String>] an array of arguments: the last

one is the message to add (String), while the beginning of the array
is made of keys to reach the attribute.

@raise [ArgumentError] when try to add a message for a key that is

already filled with incompatible message type.
This usually happens with nested attributes: if you have a `:book`
schema and the input doesn't include data for `:book`, the messages
will be `["is missing"]`. In that case you can't add an error for a
key nested under `:book`.

@since 1.1.0

@example Basic usage

require "hanami/controller"

class MyAction
  include Hanami::Action

  params do
    required(:book).schema do
      required(:isbn).filled(:str?)
    end
  end

  def call(params)
    # 1. Don't try to save the record if the params aren't valid
    return unless params.valid?

    BookRepository.new.create(params[:book])
  rescue Hanami::Model::UniqueConstraintViolationError
    # 2. Add an error in case the record wasn't unique
    params.errors.add(:book, :isbn, "is not unique")
  end
end

@example Invalid argument

require "hanami/controller"

class MyAction
  include Hanami::Action

  params do
    required(:book).schema do
      required(:title).filled(:str?)
    end
  end

  def call(params)
    puts params.to_h   # => {}
    puts params.valid? # => false
    puts params.error_messages # => ["Book is missing"]
    puts params.errors         # => {:book=>["is missing"]}

    params.errors.add(:book, :isbn, "is not unique") # => ArgumentError
  end
end
# File lib/hanami/action/params.rb, line 92
def add(*args)
  *keys, key, error = args
  _nested_attribute(keys, key) << error
rescue TypeError
  raise ArgumentError.new("Can't add #{args.map(&:inspect).join(', ')} to #{inspect}")
end

Private Instance Methods

_nested_attribute(keys, key) click to toggle source

@since 1.1.0 @api private

# File lib/hanami/action/params.rb, line 103
def _nested_attribute(keys, key)
  if keys.empty?
    self
  else
    keys.inject(self) { |result, k| result[k] ||= {} }
    dig(*keys)
  end[key] ||= []
end