class Smooth::Command

Constants

Patterns

Attributes

current_user[RW]

Commands are aware of who is running them

Public Class Methods

as(current_user) click to toggle source
# File lib/smooth/command.rb, line 4
def self.as(current_user)
  require 'smooth/command/run_proxy' unless defined?(RunProxy)
  RunProxy.new(current_user, self)
end
base_scope() click to toggle source
# File lib/smooth/command.rb, line 32
def self.base_scope
  @base_scope || :all
end
belongs_to_resource(resource) click to toggle source
# File lib/smooth/command.rb, line 44
def self.belongs_to_resource(resource)
  self.parent_resource = resource
end
configure(dsl_config_object, resource = nil) click to toggle source

DSL Hooks

# File lib/smooth/command.rb, line 124
def self.configure(dsl_config_object, resource = nil)
  resource ||= Smooth.current_resource
  klass = define_or_open(dsl_config_object, resource)

  Array(dsl_config_object.blocks).each do |blk|
    klass.class_eval(&blk)
  end

  klass
end
define_or_open(options, resource) click to toggle source
# File lib/smooth/command.rb, line 135
def self.define_or_open(options, resource)
  resource_name = resource.name.to_s.singularize
  base          = Smooth.command

  name = options.name.to_s.camelize
  klass = "#{ name }#{ resource.model_class }".gsub(/\s+/, '')

  apply_options = lambda do |k|
    k.model_class     ||= resource.model_class if resource.model_class

    k.belongs_to_resource(resource)

    k.resource_name   = resource.name.to_s
    k.command_action  = options.name.to_s
  end

  if command_klass = Object.const_get(klass) rescue nil
    return command_klass.tap(&apply_options)
  end

  parent_klass = Class.new(base)

  begin
    Object.const_set(klass, parent_klass).tap(&apply_options)
  rescue => ex
    puts ex.message
    puts "Error setting #{ klass } #{ base }. klass is a #{ klass.class }"
  end

  parent_klass
end
event_namespace() click to toggle source
# File lib/smooth/command.rb, line 79
def self.event_namespace
  @event_namespace || "#{ command_action }.#{ resource_alias }".downcase
end
execute(execution_pattern = nil, &block) click to toggle source

Allows for defining common execution pattern methods mostly for standard CRUD against scoped models

# File lib/smooth/command.rb, line 267
def self.execute(execution_pattern = nil, &block)
  send :define_method, :execute, (block || get_execution_pattern(execution_pattern))
end
filter_for_param(param) click to toggle source
# File lib/smooth/command.rb, line 217
def self.filter_for_param(param)
  optional_inputs[param] || required_inputs[param]
end
filter_options_for_param(param) click to toggle source
# File lib/smooth/command.rb, line 221
def self.filter_options_for_param(param)
  filter_for_param(param).try(:options)
end
find_serializer_for(_request_object) click to toggle source
# File lib/smooth/command.rb, line 248
def self.find_serializer_for(_request_object)
  resource = Smooth.resource(resource_name)
  resource ||= Smooth.resource("#{ resource_name }".pluralize)

  # TODO
  # We can make the preferred format something you can
  # specify via a header or parameter.  We can also restrict
  # certain serializers from certain policies.
  preferred_format = :default

  resource.fetch(:serializer, preferred_format)
end
get_execution_pattern(pattern_name) click to toggle source
# File lib/smooth/command.rb, line 295
def self.get_execution_pattern(pattern_name)
  if respond_to?("#{ pattern_name }_execution_pattern")
    return method("#{ pattern_name }_execution_pattern").to_proc
  elsif Patterns.key?(pattern_name.to_sym)
    Patterns.fetch(pattern_name.to_sym)
  else
    return method(:execute).to_proc
  end
end
input_argument_names() click to toggle source
# File lib/smooth/command.rb, line 18
def self.input_argument_names
  required_inputs.keys + optional_inputs.keys
end
interface(*args, &block) click to toggle source
# File lib/smooth/command.rb, line 14
def self.interface(*args, &block)
  send(:required, *args, &block)
end
interface_description() click to toggle source
# File lib/smooth/command.rb, line 173
def self.interface_description
  interface_documentation
end
interface_documentation() click to toggle source
# File lib/smooth/command.rb, line 177
def self.interface_documentation
  optional_inputs = input_filters.optional_inputs
  required_inputs = input_filters.required_inputs

  data = {
    required: required_inputs.keys,
    optional: optional_inputs.keys,
    filters: {}
  }

  blk = lambda do |memo, parts, required|
    key, filter = parts

    type        = filter.class.name[/^Mutations::([a-zA-Z]*)Filter$/, 1].underscore
    options     = filter.options.merge(required: required)

    value = memo[key] = {
      type: type,
      options: options.reject { |_k, v| v.nil? },
      description: input_descriptions[key]
    }

    if options[:faker]
      value[:example] = Smooth.faker(options[:faker])
    end

    memo
  end

  required_inputs.reduce(data[:filters]) do |memo, parts|
    blk.call(memo, parts, true)
  end

  optional_inputs.reduce(data[:filters]) do |memo, parts|
    blk.call(memo, parts, false)
  end

  data.to_mash
end
object_path() click to toggle source
# File lib/smooth/command.rb, line 97
def self.object_path
  resource_name.downcase + '.' + command_action
end
params(*args, &block) click to toggle source

DSL Improvements English

# File lib/smooth/command.rb, line 10
def self.params(*args, &block)
  send(:required, *args, &block)
end
parent_api() click to toggle source
# File lib/smooth/command.rb, line 48
def self.parent_api
  parent_resource.api
end
resource_alias() click to toggle source
# File lib/smooth/command.rb, line 83
def self.resource_alias
  resource_name.singularize.underscore
end
resource_name() click to toggle source
# File lib/smooth/command.rb, line 87
def self.resource_name
  value = @resource_name.to_s

  if value.empty? && model_class
    value = model_class.to_s
  end

  value
end
respond_to_request(request_object, options = {}) click to toggle source

Creates a new instance of the Smooth::Command::Response class in response to a request from the Router. It is assumed that a request object responds to: user, and params

# File lib/smooth/command.rb, line 232
def self.respond_to_request(request_object, options = {})
  klass = self

  outcome = options.fetch(:outcome) do
    klass.as(request_object.user).run(request_object.params)
  end

  response_class.new(outcome, serializer_options).tap do |response|
    response.request_headers = request_object.headers
    response.serializer = find_serializer_for(request_object)
    response.event_namespace = event_namespace
    response.command_action = command_action
    response.current_user = request_object.user
  end
end
response_class() click to toggle source
# File lib/smooth/command.rb, line 225
def self.response_class
  Smooth::Response
end
scope(setting = nil) click to toggle source
# File lib/smooth/command.rb, line 74
def self.scope(setting = nil)
  self.base_scope = setting if setting
  base_scope || :all
end
serializer_options() click to toggle source
# File lib/smooth/command.rb, line 261
def self.serializer_options
  {}
end

Public Instance Methods

event_namespace() click to toggle source
# File lib/smooth/command.rb, line 101
def event_namespace
  self.class.event_namespace
end
interface_for(filter) click to toggle source

Interface Documentation

# File lib/smooth/command.rb, line 169
def interface_for(filter)
  self.class.interface_description.filters.send(filter)
end
model_class() click to toggle source
# File lib/smooth/command.rb, line 117
def model_class
  self.class.model_class
end
object_path() click to toggle source
# File lib/smooth/command.rb, line 105
def object_path
  self.class.object_path
end
parent_api() click to toggle source
# File lib/smooth/command.rb, line 36
def parent_api
  self.class.parent_api
end
parent_resource() click to toggle source
# File lib/smooth/command.rb, line 40
def parent_resource
  self.class.parent_resource
end
resource_alias() click to toggle source
# File lib/smooth/command.rb, line 113
def resource_alias
  self.class.resource_alias
end
resource_name() click to toggle source
# File lib/smooth/command.rb, line 109
def resource_name
  self.class.resource_name
end
scope(*args) click to toggle source

Returns the model scope for this command. If a scope method is set on this command, it will make sure to scope the model by that method. It will pass whatever arguments you pass to scope to the scope method. if you pass no args, and the scope requires one, we will assume the user wants us to pass the current user of the command

# File lib/smooth/command.rb, line 57
def scope(*args)
  @scope ||= begin
               meth = model_class.send(:method, self.class.base_scope)

               if meth.arity.abs >= 1
                 args.push(current_user) if args.empty?
                 model_class.send(self.class.base_scope, *args)
               else
                 model_class.send(self.class.base_scope)
               end
             end
end
scope=(new_scope) click to toggle source
# File lib/smooth/command.rb, line 70
def scope=(new_scope)
  @scope = new_scope || scope
end
scoped_find_object() click to toggle source
# File lib/smooth/command.rb, line 287
def scoped_find_object
  @scoped_find ||= if scope.respond_to?(:find) && found = (scope.find(id) rescue nil)
                     found
  else
    add_error(:id, :not_found, "could not find a #{ resource_name } model with that id")
  end
end