class Resourcerer::Resource

Public: Representation of a model that can be found, built, and assigned attributes.

Attributes

controller[R]
name[R]
options[R]

Public Class Methods

define(klass, name, **options, &block) click to toggle source

Public: Defines a Resource and makes it accessible to a controller. For each Resource, a getter and setter is defined in the controller.

klass - The Controller class where the Resource getter will be defined. name - The name of the generated Resource. options - Config Hash for the new Resource. See Configuration::OPTIONS. block - If supplied, the block is executed to provide options.

Returns nothing.

# File lib/resourcerer/resource.rb, line 18
def self.define(klass, name, **options, &block)
  resource = new(klass, name, **options, &block)

  klass.instance_eval do
    ivar = "@resourcerer_#{ name.to_s.gsub('?', '_question_mark') }"

    private define_method(name) {
      if instance_variable_defined?(ivar)
        instance_variable_get(ivar)
      else
        instance_variable_set(ivar, resource.clone.get(self))
      end
    }

    private define_method("#{ name }=") { |value|
      instance_variable_set(ivar, value)
    }
  end
end
new(klass, name, using: [], **options, &block) click to toggle source

Public: Initalize a Resource with configuration options.

klass - The Controller class where the Resource is executed. name - The Symbol name of the Resource instance. options - Hash of options for the Configuration of the methods. block - If supplied, the block is executed to provide options.

Returns a normalized options Hash.

# File lib/resourcerer/resource.rb, line 46
def initialize(klass, name, using: [], **options, &block)
  @name = name
  @options = Configuration.new(options, &block).options

  Array.wrap(using).each do |preset|
    klass.resourcerer_configuration.fetch(preset).apply(options)
  end
end

Public Instance Methods

get(controller) click to toggle source

Public: Returns an object using the specified Resource configuration. The object will be built or found, and might be assigned attributes.

controller - The instance of the controller where the resource is fetched.

Returns the resource object.

# File lib/resourcerer/resource.rb, line 61
def get(controller)
  @controller = controller
  collection = call(:collection, call(:model))

  if id = call(:id)
    call(:find, id, collection)
  else
    call(:build, safe_attrs, collection)
  end.tap do |object|
    call(:assign, object, safe_attrs) if object && call(:assign?, object)
  end
end

Protected Instance Methods

assign(object, attrs) click to toggle source

Strategy: Assigns attributes to the found or built object.

attrs - A Hash of attributes to be assigned. object - The Resource object.

Returns nothing.

# File lib/resourcerer/resource.rb, line 129
def assign(object, attrs)
  object.assign_attributes(attrs)
end
assign?(object) click to toggle source

Strategy: Whether the attributes should be assigned.

object - The Resource object.

Returns true if attributes should be assigned, or false otherwise.

# File lib/resourcerer/resource.rb, line 138
def assign?(object)
  controller.action_name == 'update'
end
attrs() click to toggle source

Strategy: Get all the parameters of the current request.

Returns the controller's parameters for the current request.

# File lib/resourcerer/resource.rb, line 145
def attrs
  if options[:permit]
    controller.params.require(model_name).permit(*call(:permit))
  else
    params_method = "#{name}_params"
    if controller.respond_to?(params_method, true)
      controller.send(params_method)
    else
      {}
    end
  end
end
build(attrs, collection) click to toggle source

Strategy: Builds a new object on the passed-in scope.

params - A Hash of attributes for the object to-be built. scope - The collection where the object will be built from.

Returns the new object.

# File lib/resourcerer/resource.rb, line 119
def build(attrs, collection)
  collection.new(attrs)
end
collection(model = name.to_s.classify.constantize) click to toggle source

Strategy: A query or table. Designed to be overridden.

model - The Class to be scoped or queried.

Returns the object collection.

# File lib/resourcerer/resource.rb, line 81
def collection(model = name.to_s.classify.constantize)
  model
end
find(id, collection) click to toggle source

Strategy: Find an object on the supplied scope.

id - The Integer id attribute of the desired object scope - The collection that will be searched.

Returns the found object.

# File lib/resourcerer/resource.rb, line 109
def find(id, collection)
  collection.find(id)
end
id() click to toggle source

Strategy: Checks controller params to retrieve an id value.

Returns the id parameter, if any, or nil.

# File lib/resourcerer/resource.rb, line 98
def id
  ["#{name}_id", "#{model_name}_id", 'id'].uniq.
    map { |id| controller.params[id] }.find(&:present?)
end
model() click to toggle source

Strategy: Converts a name into a standard Class name.

Examples

'egg_and_hams'.model # => EggAndHam

Returns a standard Class name.

# File lib/resourcerer/resource.rb, line 91
def model
  options.key?(:collection) ? call(:collection).klass : collection
end

Private Instance Methods

call(name, *args) click to toggle source

Internal: Invokes a Proc that was passed as an option, or the default strategy for that function.

# File lib/resourcerer/resource.rb, line 178
def call(name, *args)
  memoize(name) {
    if options.key?(name)
      execute_option_function(options[name], *args)
    else
      send(name, *args)
    end
  }
end
execute_option_function(function, *args) click to toggle source

Internal: Invokes a Proc that was passed as an option. The Proc executes within the context of the controller.

# File lib/resourcerer/resource.rb, line 190
def execute_option_function(function, *args)
  args = args.first(function.parameters.length)
  controller.instance_exec(*args, &function)
end
memoize(name) { || ... } click to toggle source

Internal: Helper method to perform simple memoization.

# File lib/resourcerer/resource.rb, line 196
def memoize(name)
  ivar = "@#{ name.to_s.gsub('?', '_question_mark') }"

  if instance_variable_defined?(ivar)
    instance_variable_get(ivar)
  else
    instance_variable_set(ivar, yield)
  end
end
model_name() click to toggle source

Internal: Returns a Symbol name that follows the parameter convention.

# File lib/resourcerer/resource.rb, line 168
def model_name
  @model_name ||= if defined?(ActiveModel::Name)
    ActiveModel::Name.new(call(:model)).param_key
  else
    call(:model).name.underscore
  end.to_sym
end
safe_attrs() click to toggle source

Internal: Avoids assigning attributes when the request is a GET request.

Returns the controller's parameters for the current request.

# File lib/resourcerer/resource.rb, line 163
def safe_attrs
  controller.request.get? ? {} : call(:attrs)
end