class Paradocs::Field

Constants

Result

Attributes

default_block[R]
key[R]
meta_data[R]
policies[R]

Public Class Methods

new(key) click to toggle source
# File lib/paradocs/field.rb, line 10
def initialize(key)
  @key = key
  @policies = []
  @default_block = nil
  @meta_data = {}
  @policies = []
  @mutation_block = nil
  @expects_mutation = nil
end

Public Instance Methods

default(value) click to toggle source
# File lib/paradocs/field.rb, line 29
def default(value)
  meta default: value
  @default_block = (value.respond_to?(:call) ? value : ->(key, payload, context) { value })
  self
end
expects_mutation?() click to toggle source
# File lib/paradocs/field.rb, line 46
def expects_mutation?
  mutates_schema? && @expects_mutation
end
meta(hash = nil) click to toggle source
# File lib/paradocs/field.rb, line 20
def meta(hash = nil)
  @meta_data = @meta_data.merge(hash) if hash.is_a?(Hash)
  self
end
mutates_schema!(&block) click to toggle source
# File lib/paradocs/field.rb, line 35
def mutates_schema!(&block)
  @mutation_block   ||= block if block_given?
  @expects_mutation = @expects_mutation.nil? && true
  meta mutates_schema: @mutation_block
  @mutation_block
end
mutates_schema?() click to toggle source
# File lib/paradocs/field.rb, line 42
def mutates_schema?
  !!@mutation_block
end
policy(key, *args) click to toggle source
# File lib/paradocs/field.rb, line 50
def policy(key, *args)
  pol = lookup(key, args)

  meta pol.meta_data
  policies << pol
  self
end
Also aliased as: type, rule
possible_errors() click to toggle source
# File lib/paradocs/field.rb, line 25
def possible_errors
  meta_data.map { |_, v| v[:errors] if v.is_a?(Hash) }.flatten.compact
end
resolve(payload, context) click to toggle source
# File lib/paradocs/field.rb, line 86
def resolve(payload, context)
  eligible = payload.key?(key)
  value = payload[key] # might be nil

  if !eligible && has_default?
    eligible = true
    value = default_block.call(key, payload, context)
    payload[key] = value
  end
  policies.each do |policy|
    # pass schema additional data to the each policy
    policy.environment = context.environment if policy.respond_to?(:environment=)
    if !policy.eligible?(value, key, payload)
      eligible = false
      if has_default?
        eligible = true
        value = default_block.call(key, payload, context)
      end
      break
    else
      value, valid = resolve_one(policy, value, payload, context)

      unless valid
        eligible = true # eligible, but has errors
        break # only one error at a time
      end
    end
  end

  Result.new(eligible, value)
end
rule(key, *args)
Alias for: policy
schema(sc = nil, &block) click to toggle source
# File lib/paradocs/field.rb, line 61
def schema(sc = nil, &block)
  sc = (sc ? sc : Schema.new(&block))
  meta schema: sc
  policy sc.schema
end
subschema_for_mutation(payload, env) click to toggle source
# File lib/paradocs/field.rb, line 80
def subschema_for_mutation(payload, env)
  subschema_name = @mutation_block.call(payload[key], key, payload, env) if @mutation_block
  @expects_mutation = false
  subschema_name
end
transparent?() click to toggle source
# File lib/paradocs/field.rb, line 67
def transparent?
  !!meta_data[:transparent]
end
type(key, *args)
Alias for: policy
visit(meta_key = nil) { |self| ... } click to toggle source
# File lib/paradocs/field.rb, line 71
def visit(meta_key = nil, &visitor)
  if sc = meta_data[:schema]
    r = sc.visit(meta_key, &visitor)
    (meta_data[:type] == :array) ? [r] : r
  else
    meta_key ? meta_data[meta_key] : yield(self)
  end
end

Private Instance Methods

has_default?() click to toggle source
# File lib/paradocs/field.rb, line 145
def has_default?
  !!default_block
end
lookup(key, args) click to toggle source
# File lib/paradocs/field.rb, line 149
def lookup(key, args)
  obj = key.is_a?(Symbol) ? Paradocs.registry.policies[key] : key

  raise ConfigurationError, "No policies defined for #{key.inspect}" unless obj
  obj.respond_to?(:new) ? obj.new(*args) : obj
end
resolve_one(policy, value, payload, context) click to toggle source
# File lib/paradocs/field.rb, line 121
def resolve_one(policy, value, payload, context)
  begin
    value = policy.coerce(value, key, context)
    valid = policy.valid?(value, key, payload)

    context.add_error(policy.message) unless valid
    [value, valid]
  rescue *(policy.try(:errors) || []) => e
    # context.add_error e.message # NOTE: do we need it?
    raise e
  rescue *(policy.try(:silent_errors) || []) => e
    context.add_error e.message
  rescue StandardError => e
    raise e if policy.is_a? Paradocs::Schema # from the inner level, just reraise
    if Paradocs.config.explicit_errors
      error = ConfigurationError.new("<#{e.class}:#{e.message}> should be registered in the policy")
      error.set_backtrace(e.backtrace)
      raise error
    end
    context.add_error policy.message unless Paradocs.config.explicit_errors
    [value, false]
  end
end