class HaveAPI::Params

Attributes

action[RW]
params[R]

Public Class Methods

new(direction, action) click to toggle source
# File lib/haveapi/params.rb, line 20
def initialize(direction, action)
  @direction = direction
  @params = []
  @action = action
  @cache = {}
  @blocks = []
end

Public Instance Methods

[](name) click to toggle source
# File lib/haveapi/params.rb, line 270
def [](name)
  @params.detect { |p| p.name == name }
end
add_block(b) click to toggle source
# File lib/haveapi/params.rb, line 28
def add_block(b)
  @blocks << b
end
belongs_to(name, **kwargs)
Alias for: resource
bool(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 96
def bool(name, **kwargs)
  add_param(name, apply(kwargs, type: Boolean))
end
check_layout(params) click to toggle source

First step of validation. Check if input is in correct namespace and has a correct layout.

# File lib/haveapi/params.rb, line 206
def check_layout(params)
  if (params[namespace].nil? || !valid_layout?(params)) && any_required_params?
    raise ValidationError.new('invalid input layout', {})
  end

  case layout
  when :object, :hash
    params[namespace] ||= {}

  when :object_list, :hash_list
    params[namespace] ||= []
  end
end
clone() click to toggle source
Calls superclass method
# File lib/haveapi/params.rb, line 38
def clone
  obj = super
  params = @params
  blocks = @blocks

  obj.instance_eval do
    @params = params.dup
    @cache = {}
    @blocks = blocks.dup
  end

  obj
end
custom(name, **kwargs, &block) click to toggle source

Action returns custom data.

# File lib/haveapi/params.rb, line 165
def custom(name, **kwargs, &block)
  add_param(name, apply(kwargs, type: Custom, clean: block))
end
datetime(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 111
def datetime(name, **kwargs)
  add_param(name, apply(kwargs, type: Datetime))
end
describe(context) click to toggle source
# File lib/haveapi/params.rb, line 169
def describe(context)
  context.layout = layout

  ret = { parameters: {} }
  ret[:layout] = layout
  ret[:namespace] = namespace
  ret[:format] = @structure if @structure

  @params.each do |p|
    ret[:parameters][p.name] = p.describe(context)
  end

  ret[:parameters] = if @direction == :input
                       context.authorization.filter_input(
                         @params,
                         ModelAdapters::Hash.output(context, ret[:parameters])
                       )
                     else
                       context.authorization.filter_output(
                         @params,
                         ModelAdapters::Hash.output(context, ret[:parameters])
                       )
                     end

  ret
end
exec() click to toggle source
# File lib/haveapi/params.rb, line 32
def exec
  @blocks.each do |b|
    instance_exec(&b)
  end
end
float(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 107
def float(name, **kwargs)
  add_param(name, apply(kwargs, type: Float))
end
foreign_key(name, **kwargs)
Alias for: integer
id(name, **kwargs)
Alias for: integer
integer(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 100
def integer(name, **kwargs)
  add_param(name, apply(kwargs, type: Integer))
end
Also aliased as: id, foreign_key
layout() click to toggle source
# File lib/haveapi/params.rb, line 52
def layout
  return @cache[:layout] if @cache[:layout]

  @cache[:layout] = @layout || :object
end
layout=(l) click to toggle source
# File lib/haveapi/params.rb, line 58
def layout=(l)
  @layout = l if l
end
namespace() click to toggle source
# File lib/haveapi/params.rb, line 62
def namespace
  return @cache[:namespace] unless @cache[:namespace].nil?
  return @cache[:namespace] = @namespace unless @namespace.nil?

  n = @action.resource.resource_name.underscore
  n = n.pluralize if %i[object_list hash_list].include?(layout)
  @cache[:namespace] = n.to_sym
end
namespace=(n) click to toggle source
# File lib/haveapi/params.rb, line 71
def namespace=(n)
  @namespace = false if n === false
  @namespace = n.to_sym if n
end
optional(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 80
def optional(name, **kwargs)
  add_param(name, apply(kwargs, required: false))
end
param(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 115
def param(name, **kwargs)
  add_param(name, kwargs)
end
password(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 92
def password(name, **kwargs)
  add_param(name, apply(kwargs, type: String, protected: true))
end
patch(name, **changes) click to toggle source
# File lib/haveapi/params.rb, line 153
def patch(name, **changes)
  @params.detect { |p| p.name == name }.patch(changes)
end
references(name, **kwargs)
Alias for: resource
remove(name) click to toggle source
# File lib/haveapi/params.rb, line 157
def remove(name)
  i = @params.index { |p| p.name == name }
  raise "Parameter #{name.inspect} not found" if i.nil?

  @params.delete_at(i)
end
requires(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 76
def requires(name, **kwargs)
  add_param(name, apply(kwargs, required: true))
end
resource(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 146
def resource(name, **kwargs)
  add_resource(name, kwargs)
end
Also aliased as: references, belongs_to
string(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 84
def string(name, **kwargs)
  add_param(name, apply(kwargs, type: String))
end
text(name, **kwargs) click to toggle source
# File lib/haveapi/params.rb, line 88
def text(name, **kwargs)
  add_param(name, apply(kwargs, type: Text))
end
use(name, include: nil, exclude: nil) click to toggle source
# File lib/haveapi/params.rb, line 119
def use(name, include: nil, exclude: nil)
  @include_back ||= []
  @exclude_back ||= []

  block = @action.resource.params(name)

  return unless block

  @include_back << @include.clone if @include
  @exclude_back << @exclude.clone if @exclude

  if include
    @include ||= []
    @include.concat(include)
  end

  if exclude
    @exclude ||= []
    @exclude.concat(exclude)
  end

  instance_eval(&block)

  @include = @include_back.pop if @include
  @exclude = @exclude_back.pop if @exclude
end
validate(params) click to toggle source

Third step of validation. Check if all required params are present, convert params to correct data types, set default values if necessary.

# File lib/haveapi/params.rb, line 222
def validate(params)
  errors = {}

  layout_aware(params) do |input|
    # First run - coerce values to correct types
    @params.each do |p|
      if p.required? && input[p.name].nil?
        errors[p.name] = ['required parameter missing']
        next
      end

      unless input.has_key?(p.name)
        input[p.name] = p.default if p.respond_to?(:fill?) && p.fill?
        next
      end

      begin
        cleaned = p.clean(input[p.name])
      rescue ValidationError => e
        errors[p.name] ||= []
        errors[p.name] << e.message
        next
      end

      input[p.name] = cleaned if cleaned != :_nil
    end

    # Second run - validate parameters
    @params.each do |p|
      next if errors.has_key?(p.name)
      next if input[p.name].nil?

      res = p.validate(input[p.name], input)

      unless res === true
        errors[p.name] ||= []
        errors[p.name].concat(res)
      end
    end
  end

  unless errors.empty?
    raise ValidationError.new('input parameters not valid', errors)
  end

  params
end
validate_build() click to toggle source
# File lib/haveapi/params.rb, line 196
def validate_build
  m = :"validate_build_#{@direction}"

  @params.each do |p|
    p.send(m) if p.respond_to?(m)
  end
end

Private Instance Methods

add_param(name, kwargs) click to toggle source
# File lib/haveapi/params.rb, line 276
def add_param(name, kwargs)
  p = Parameters::Typed.new(name, kwargs)

  return if @include && !@include.include?(p.name)
  return if @exclude && @exclude.include?(p.name)

  @params << p unless param_exists?(p.name)
end
add_resource(name, kwargs) click to toggle source
# File lib/haveapi/params.rb, line 285
def add_resource(name, kwargs)
  r = Parameters::Resource.new(name, **kwargs)

  return if @include && !@include.include?(r.name)
  return if @exclude && @exclude.include?(r.name)

  @params << r unless param_exists?(r.name)
end
any_required_params?() click to toggle source
# File lib/haveapi/params.rb, line 331
def any_required_params?
  @params.each do |p|
    return true if p.required?
  end

  false
end
apply(kwargs, **default) click to toggle source
# File lib/haveapi/params.rb, line 298
def apply(kwargs, **default)
  kwargs.update(default)
  kwargs
end
layout_aware(params, &) { |ns ? params : params| ... } click to toggle source
# File lib/haveapi/params.rb, line 316
def layout_aware(params, &)
  ns = namespace

  case layout
  when :object, :hash
    yield(ns ? params[namespace] : params)

  when :object_list, :hash_list
    (ns ? params[namespace] : params).each(&)

  else
    false
  end
end
param_exists?(name) click to toggle source
# File lib/haveapi/params.rb, line 294
def param_exists?(name)
  !@params.detect { |p| p.name == name }.nil?
end
valid_layout?(params) click to toggle source
# File lib/haveapi/params.rb, line 303
def valid_layout?(params)
  case layout
  when :object, :hash
    params[namespace].is_a?(Hash)

  when :object_list, :hash_list
    params[namespace].is_a?(Array)

  else
    false
  end
end