class Smooth::Resource

Attributes

_commands[R]

These store the configuration values for the various objects belonging to the resource.

_examples[R]

These store the configuration values for the various objects belonging to the resource.

_queries[R]

These store the configuration values for the various objects belonging to the resource.

_routes[R]

These store the configuration values for the various objects belonging to the resource.

_serializers[R]

These store the configuration values for the various objects belonging to the resource.

api_name[RW]
description[RW]
group_description[RW]
model_class[RW]
object_descriptions[R]

These store the configuration values for the various objects belonging to the resource.

resource_name[RW]

Public Class Methods

new(resource_name, options = {}, &block) click to toggle source
# File lib/smooth/resource.rb, line 23
def initialize(resource_name, options = {}, &block)
  @resource_name  = resource_name
  @options        = options

  @model_class    = options.fetch(:model, nil)

  @_serializers   = {}.to_mash
  @_commands      = {}.to_mash
  @_queries       = {}.to_mash
  @_routes        = {}.to_mash
  @_examples      = {}.to_mash

  @object_descriptions = {
    commands: {},
    queries: {},
    serializers: {},
    routes: {},
    examples: {}
  }

  @loaded         = false

  instance_eval(&block) if block_given?

  load!
end

Public Instance Methods

api() click to toggle source
# File lib/smooth/resource.rb, line 149
def api
  Smooth.fetch_api(api_name || :default)
end
apply_options(*opts) click to toggle source
# File lib/smooth/resource.rb, line 153
def apply_options(*opts)
  @options.send(:merge!, *opts)
end
available_commands() click to toggle source
# File lib/smooth/resource.rb, line 80
def available_commands
  _commands.keys
end
available_examples() click to toggle source
# File lib/smooth/resource.rb, line 97
def available_examples
  _examples.keys
end
available_queries() click to toggle source
# File lib/smooth/resource.rb, line 84
def available_queries
  _queries.keys
end
available_routes() click to toggle source

SHORT CIRCUIT

# File lib/smooth/resource.rb, line 93
def available_routes
  []
end
available_serializers() click to toggle source
# File lib/smooth/resource.rb, line 88
def available_serializers
  _serializers.keys
end
belongs_to(*args) click to toggle source
# File lib/smooth/resource.rb, line 113
def belongs_to(*args)
  model_class.send(:belongs_to, *args)
end
command(command_name, *args, &block) click to toggle source
# File lib/smooth/resource.rb, line 202
def command(command_name, *args, &block)
  if args.empty? && !block_given? && exists = fetch(:command, command_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:command, command_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = (specified_class.constantize rescue nil) if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.command_class)

  config = _commands[command_name.to_sym] ||= Hashie::Mash.new(options: {}, name: command_name, blocks: [block].compact, class: specified_class)

  config.options.merge!(options)
  config.description = provided_description unless provided_description.nil?

  config
end
command_classes() click to toggle source
# File lib/smooth/resource.rb, line 298
def command_classes
  @commands && @commands.values
end
describe_object(object_type, object_name, with_value = {}) click to toggle source
# File lib/smooth/resource.rb, line 157
def describe_object(object_type, object_name, with_value = {})
  bucket = documentation_for(object_type, object_name)

  with_value = { description: with_value } if with_value.is_a?(String)

  bucket[:description] = with_value.fetch(:description, with_value['description'])
  bucket[:description_args] = with_value.fetch(:args, [])
end
documentation_for(object_type, object_name) click to toggle source
# File lib/smooth/resource.rb, line 166
def documentation_for(object_type, object_name)
  object_descriptions[object_type.to_s.pluralize.to_sym][object_name.to_sym] ||= {}
end
examples(options = {}, &_block) click to toggle source
# File lib/smooth/resource.rb, line 276
def examples(options = {}, &_block)
  if options.empty? && !block_given?
    return @examples
  end
end
expand_routes(from_attributes = {}) click to toggle source
# File lib/smooth/resource.rb, line 272
def expand_routes(from_attributes = {})
  router.expand_routes(from_attributes)
end
expanded_documentation_for(object_type, object_name) click to toggle source
# File lib/smooth/resource.rb, line 170
def expanded_documentation_for(object_type, object_name)
  base = documentation_for(object_type, object_name)
  klass = object_class_for(object_type, object_name)

  base.merge!(class: klass.to_s, interface: klass && klass.interface_documentation)
end
fetch(object_type, object_key) click to toggle source
# File lib/smooth/resource.rb, line 131
def fetch(object_type, object_key)
  source = instance_variable_get("@#{ object_type }s") rescue nil
  source = @queries if object_type.to_sym == :query
  source && source.fetch(object_key.to_s.downcase)
end
fetch_config(object_type, object_key) click to toggle source
# File lib/smooth/resource.rb, line 125
def fetch_config(object_type, object_key)
  source = send("_#{ object_type }s") rescue nil
  source = @_queries if object_type.to_sym == :query
  source && source.fetch(object_key.to_s.downcase.to_sym)
end
has_and_belongs_to_many(*args) click to toggle source
# File lib/smooth/resource.rb, line 121
def has_and_belongs_to_many(*args)
  model_class.send(:has_and_belongs_to_many, *args)
end
has_many(*args) click to toggle source
# File lib/smooth/resource.rb, line 109
def has_many(*args)
  model_class.send(:has_many, *args)
end
has_one(*args) click to toggle source
# File lib/smooth/resource.rb, line 117
def has_one(*args)
  model_class.send(:has_one, *args)
end
interface_documentation() click to toggle source

The Smooth Resources are capable of exposing information about their configuration, which makes auto generating documentation for their API very easy, but this can also be used to generate client side models or control form / report builder interfaces.

# File lib/smooth/resource.rb, line 54
def interface_documentation
  resource = self

  @interface ||= begin
                   base = {
                     routes: (router.interface_documentation rescue {})
                   }

                   resource.object_descriptions.keys.reduce(base) do |memo, type|
                     memo.tap do
                       bucket = memo[type] ||= {}
                       resource.send("available_#{ type }").each do |object_name|
                         docs = resource.expanded_documentation_for(type, object_name)
                         bucket[object_name] = docs
                       end
                     end
                   end
                 end.to_mash
end
load!() click to toggle source
# File lib/smooth/resource.rb, line 141
def load!
  configure_commands
  configure_serializers
  configure_queries
  configure_routes
  configure_examples
end
loaded?() click to toggle source
# File lib/smooth/resource.rb, line 137
def loaded?
  !!@loaded
end
model(&block) click to toggle source
# File lib/smooth/resource.rb, line 256
def model(&block)
  model_class.instance_eval(&block)
end
name() click to toggle source
# File lib/smooth/resource.rb, line 105
def name
  resource_name
end
object_class_for(object_type, object_name) click to toggle source
# File lib/smooth/resource.rb, line 177
def object_class_for(object_type, object_name)
  fetch(object_type.to_s.singularize.to_sym, object_name.to_sym)
rescue => e
  binding.pry
end
part_of_the(group_description) click to toggle source

Resource groups allow for easier organization of the documentation and things of that nature.

# File lib/smooth/resource.rb, line 76
def part_of_the(group_description)
  @group_description = group_description
end
query(query_name = 'Default', *args, &block) click to toggle source
# File lib/smooth/resource.rb, line 225
def query(query_name = 'Default', *args, &block)
  if args.empty? && !block_given? && exists = fetch(:query, query_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:query, query_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = (specified_class.constantize rescue nil) if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.query_class)

  config = _queries[query_name.downcase.to_sym] ||= Hashie::Mash.new(options: {}, name: query_name, blocks: [block].compact, class: specified_class)
  config.options.merge!(options)
  config.description = provided_description unless provided_description.nil?

  config
end
query_class(reference = :default) click to toggle source
# File lib/smooth/resource.rb, line 286
def query_class(reference = :default)
  @queries.fetch(reference, query_classes.first)
end
query_classes() click to toggle source
# File lib/smooth/resource.rb, line 294
def query_classes
  @queries && @queries.values
end
route_table() click to toggle source
# File lib/smooth/resource.rb, line 268
def route_table
  router.route_table
end
router() click to toggle source
# File lib/smooth/resource.rb, line 264
def router
  @router || routes
end
routes(options = {}, &block) click to toggle source
# File lib/smooth/resource.rb, line 247
def routes(options = {}, &block)
  return @router unless block_given?

  @router ||= Smooth::Resource::Router.new(self, options).tap do |router|
    router.instance_eval(&block)
    router.build_methods_table
  end
end
scope(*args, &block) click to toggle source
# File lib/smooth/resource.rb, line 260
def scope(*args, &block)
  model_class.send(:scope, *args, &block)
end
serializer(serializer_name = 'Default', *args, &block) click to toggle source
# File lib/smooth/resource.rb, line 183
def serializer(serializer_name = 'Default', *args, &block)
  if args.empty? && !block_given? && exists = fetch(:serializer, serializer_name)
    return exists
  end

  options = args.extract_options!

  provided_description = options.fetch(:description, inline_description)

  describe_object(:serializer, serializer_name.downcase, provided_description) unless provided_description.empty?

  specified_class = args.first
  specified_class = specified_class.constantize if specified_class.is_a?(String)
  specified_class = nil if specified_class && !(specified_class <= Smooth.config.serializer_class)

  config = _serializers[serializer_name.downcase.to_sym] ||= Hashie::Mash.new(options: {}, name: serializer_name, blocks: [block].compact, class: specified_class)
  config.description = provided_description unless provided_description.nil?
end
serializer_class(reference = :default) click to toggle source
# File lib/smooth/resource.rb, line 282
def serializer_class(reference = :default)
  @serializers.fetch(reference, serializer_classes.first)
end
serializer_classes() click to toggle source
# File lib/smooth/resource.rb, line 290
def serializer_classes
  @serializers && @serializers.values
end

Protected Instance Methods

configure_commands() click to toggle source
# File lib/smooth/resource.rb, line 304
def configure_commands
  resource = self

  @commands = _commands.reduce({}.to_mash) do |memo, p|
    ref, cfg = p
    memo[cfg.name.downcase] = Smooth::Command.configure(cfg, resource)
    memo
  end
end
configure_examples() click to toggle source
# File lib/smooth/resource.rb, line 341
def configure_examples
  @examples = {}
end
configure_queries() click to toggle source
# File lib/smooth/resource.rb, line 327
def configure_queries
  resource = self

  @queries = _queries.reduce({}.to_mash) do |memo, p|
    ref, cfg = p
    memo[cfg.name.downcase] = Smooth::Query.configure(cfg, resource)
    memo
  end
end
configure_routes() click to toggle source
# File lib/smooth/resource.rb, line 337
def configure_routes
  @routes = {}
end
configure_serializers() click to toggle source
# File lib/smooth/resource.rb, line 314
def configure_serializers
  resource = self

  @serializers = _serializers.reduce({}.to_mash) do |memo, p|
    memo.tap do
      ref, cfg = p
      serializer = memo[cfg.name.downcase] = Smooth::Serializer.configure(cfg, resource)

      serializer.return_ids_for_relationships! if Smooth.config.embed_relationships_as == :ids
    end
  end
end