module Praxis::ResourceDefinition::ClassMethods

Attributes

actions[R]
controller[RW]
metadata[R]

opaque hash of user-defined medata, used to decorate the definition, and also available in the generated JSON documents

parent_prefix[R]
responses[R]
routing_prefix[W]
traits[R]
version_options[R]
version_prefix[R]

Public Instance Methods

action(name, &block) click to toggle source
# File lib/praxis/resource_definition.rb, line 285
def action(name, &block)
  raise ArgumentError, "can not create ActionDefinition without block" unless block_given?
  raise ArgumentError, "Action names must be defined using symbols (Got: #{name} (of type #{name.class}))" unless name.is_a? Symbol
  @actions[name] = ActionDefinition.new(name, self, &block)
end
action_defaults(&block) click to toggle source
# File lib/praxis/resource_definition.rb, line 249
def action_defaults(&block)
  if block_given?
    @action_defaults.instance_eval(&block)
  end

  @action_defaults
end
canonical_path(action_name=nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 206
def canonical_path(action_name=nil)
  if action_name
    raise "Canonical path for #{self.name} is already defined as: '#{@canonical_action_name}'. 'canonical_path' can only be defined once." if @canonical_action_name
    @canonical_action_name = action_name
  else
    # Resolution of the actual action definition needs to be done lazily, since we can use the `canonical_path` stanza
    # at the top of the resource, well before the actual action is defined.
    unless @canonical_action
      href_action = @canonical_action_name || DEFAULT_RESOURCE_HREF_ACTION
      @canonical_action = actions.fetch(href_action) do
        raise "Error: trying to set canonical_href of #{self.name}. Action '#{href_action}' does not exist"
      end
    end
    return @canonical_action
  end
end
describe(context: nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 300
def describe(context: nil)
  {}.tap do |hash|
    hash[:description] = description
    hash[:media_type] = media_type.describe(true) if media_type
    hash[:actions] = actions.values.collect{|action| action.describe(context: context)}
    hash[:name] = self.name
    hash[:parent] = self.parent.id if self.parent
    hash[:display_name] = self.display_name
    hash[:metadata] = metadata
    hash[:traits] = self.traits
  end
end
description(text=nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 291
def description(text=nil)
  @description = text if text
  @description
end
display_name( string=nil ) click to toggle source
# File lib/praxis/resource_definition.rb, line 83
def display_name( string=nil )
  unless string
    return  @display_name ||= self.name.split("::").last  # Best guess at a display name?
  end
  @display_name = string
end
headers(**opts, &block) click to toggle source
# File lib/praxis/resource_definition.rb, line 271
def headers(**opts, &block)
  warn 'DEPRECATED: ResourceDefinition.headers is deprecated. Use action_defaults instead.'
  action_defaults do
    headers **opts, &block
  end
end
id() click to toggle source
# File lib/praxis/resource_definition.rb, line 296
def id
  self.name.gsub('::'.freeze,'-'.freeze)
end
inherit_params_from_parent(parent_action, **mapping) click to toggle source
# File lib/praxis/resource_definition.rb, line 163
def inherit_params_from_parent(parent_action, **mapping)
  actions.each do |name, action|
    action.params do
      mapping.each do |parent_name, name|
        next if action.params && action.params.attributes.key?(name)

        parent_attribute = parent_action.params.attributes[parent_name]

        attribute name, parent_attribute.type, parent_attribute.options
      end
    end
  end

end
media_type(media_type=nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 112
def media_type(media_type=nil)
  return @media_type if media_type.nil?

  if media_type.kind_of?(String)
    media_type = SimpleMediaType.new(media_type)
  end
  @media_type = media_type
end
nodoc!() click to toggle source
# File lib/praxis/resource_definition.rb, line 313
def nodoc!
  metadata[:doc_visibility] = :none
end
on_finalize() click to toggle source
# File lib/praxis/resource_definition.rb, line 90
def on_finalize
  if block_given?
    @on_finalize << Proc.new
  end

  @on_finalize
end
params(type=Attributor::Struct, **opts, &block) click to toggle source
# File lib/praxis/resource_definition.rb, line 257
def params(type=Attributor::Struct, **opts, &block)
  warn 'DEPRECATED: ResourceDefinition.params is deprecated. Use it in action_defaults instead.'
  action_defaults do
    params type, **opts, &block
  end
end
parent(parent=nil, **mapping) click to toggle source
# File lib/praxis/resource_definition.rb, line 122
def parent(parent=nil, **mapping)
  return @parent if parent.nil?

  @routing_prefix = nil # reset routing_prefix

  parent_action = parent.canonical_path
  parent_route = parent_action.primary_route.path

  # if a mapping is passed, it *must* resolve any param name conflicts
  unless mapping.any?
    # assume last capture is the relevant one to replace
    # if not... then I quit.
    parent_param_name = parent_route.names.last

    # more assumptions about names
    parent_name = parent.name.demodulize.underscore.singularize

    # put it together to find what we should call this new param
    param = "#{parent_name}_#{parent_param_name}".to_sym
    mapping[parent_param_name.to_sym] = param
  end

  # complete the mapping and massage the route
  parent_route.names.collect(&:to_sym).each do |name|
    if mapping.key?(name)
      param = mapping[name]
      # FIXME: this won't handle URI Template type paths, ie '/{parent_id}'
      prefixed_path = parent_action.primary_route.prefixed_path
      @parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param.to_s}\\3")
    else
      mapping[name] = name
    end
  end

  self.on_finalize do
    self.inherit_params_from_parent(parent_action, **mapping)
  end

  @parent = parent
end
parse_href(path) click to toggle source
# File lib/praxis/resource_definition.rb, line 227
def parse_href(path)
  if path.kind_of?(::URI::Generic)
    path = path.path
  end
  param_values = canonical_path.primary_route.path.params(path)
  attrs = canonical_path.params.attributes
  param_values.each_with_object({}) do |(key,value),hash|
    hash[key.to_sym] = attrs[key.to_sym].load(value,[key])
  end
rescue => e
  raise Praxis::Exception.new("Error parsing or coercing parameters from href: #{path}\n"+e.message)
end
payload(type=Attributor::Struct, **opts, &block) click to toggle source
# File lib/praxis/resource_definition.rb, line 264
def payload(type=Attributor::Struct, **opts, &block)
  warn 'DEPRECATED: ResourceDefinition.payload is deprecated. Use action_defaults instead.'
  action_defaults do
    payload type, **opts, &block
  end
end
prefix(prefix=nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 106
def prefix(prefix=nil)
  return @prefix if prefix.nil?
  @routing_prefix = nil # reset routing_prefix
  @prefix = prefix
end
response(name, **args) click to toggle source
# File lib/praxis/resource_definition.rb, line 278
def response(name, **args)
  warn 'DEPRECATED: ResourceDefinition.response is deprecated. Use action_defaults instead.'
  action_defaults do
    response name, **args
  end
end
routing(&block) click to toggle source

FIXME: this is inconsistent with the rest of the magic DSL convention.

# File lib/praxis/resource_definition.rb, line 99
def routing(&block)
  warn "DEPRECATED: ResourceDefinition.routing is deprecated use prefix directly instead."

  # eval this assuming it will only call #prefix
  self.instance_eval(&block)
end
routing_prefix() click to toggle source
# File lib/praxis/resource_definition.rb, line 180
def routing_prefix
  return @routing_prefix if @routing_prefix

  @routing_prefix = parent_prefix + prefix
end
to_href( params ) click to toggle source
# File lib/praxis/resource_definition.rb, line 223
def to_href( params )
  canonical_path.primary_route.path.expand(params)
end
trait(trait_name) click to toggle source
# File lib/praxis/resource_definition.rb, line 240
def trait(trait_name)
  unless ApiDefinition.instance.traits.has_key? trait_name
    raise Exceptions::InvalidTrait.new("Trait #{trait_name} not found in the system")
  end
  trait = ApiDefinition.instance.traits.fetch(trait_name)
  @traits << trait_name
end
Also aliased as: use
use(trait_name)
Alias for: trait
version(version=nil, options=nil) click to toggle source
# File lib/praxis/resource_definition.rb, line 187
def version(version=nil, options=nil)
  return @version unless version

  @version = version

  unless options.nil?
    warn 'DEPRECATED: ResourceDefinition.version with options is no longer supported. Define in api global info instead.'

    @version_options = options
    version_using = Array(@version_options[:using])
    if version_using.include?(:path)
      @version_prefix = "#{Praxis::Request::path_version_prefix}#{self.version}"
    end
  end

  @action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version )
end