class Praxis::Mapper::Resource

Attributes

decorations[R]
model_map[R]
properties[R]
record[RW]

Public Class Methods

_finalize!() click to toggle source
Calls superclass method
# File lib/praxis-mapper/resource.rb, line 80
def self._finalize!
  finalize_resource_delegates
  define_model_accessors
  define_decorators

  super
end
all(condition={}) click to toggle source
# File lib/praxis-mapper/resource.rb, line 166
def self.all(condition={})
  records = self.model.all(condition)

  self.wrap(records)
end
decorate(name, &block) click to toggle source
# File lib/praxis-mapper/resource.rb, line 72
def self.decorate(name, &block)
  self.decorations[name] = Class.new(ResourceDecorator, &block)
end
define_accessor(name) click to toggle source
# File lib/praxis-mapper/resource.rb, line 236
    def self.define_accessor(name)
      if name.to_s =~ /\?/
        ivar_name = "is_#{name.to_s[0..-2]}"
      else
        ivar_name = "#{name}"
      end

      module_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{name}
        return @__#{ivar_name} if defined? @__#{ivar_name}
        @__#{ivar_name} = record.#{name}
      end
      RUBY
    end
define_decorator(name, block) click to toggle source
# File lib/praxis-mapper/resource.rb, line 116
    def self.define_decorator(name, block)
      unless self.instance_methods.include?(name)
        # assume it'll be a regular accessor and create it
        self.define_accessor(name)
      end
      # alias original method and wrap it
      raw_name = "_raw_#{name}"
      alias_method(raw_name.to_sym, name)

      module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{name}
          object = self.#{raw_name}
          self.class.decorations[#{name.inspect}].new(self, object)
        end
      RUBY
    end
define_decorators() click to toggle source
# File lib/praxis-mapper/resource.rb, line 110
def self.define_decorators
  self.decorations.each do |name,block|
    self.define_decorator(name, block)
  end
end
define_model_accessors() click to toggle source
# File lib/praxis-mapper/resource.rb, line 99
def self.define_model_accessors
  return if model.nil?

  model.associations.each do |k,v|
    unless self.instance_methods.include? k
      define_model_association_accessor(k,v)
    end
  end
end
define_model_association_accessor(name, association_spec) click to toggle source

Defines wrappers for model associations that return Resources

# File lib/praxis-mapper/resource.rb, line 184
    def self.define_model_association_accessor(name, association_spec)
      association_model = association_spec.fetch(:model)
      association_resource_class = model_map[association_model]

      if association_resource_class
        module_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{name}
          records = record.#{name}
            return nil if records.nil?
          @__#{name} ||= #{association_resource_class}.wrap(records)
        end
        RUBY
      end
    end
define_resource_delegate(resource_name, resource_attribute) click to toggle source
# File lib/praxis-mapper/resource.rb, line 199
def self.define_resource_delegate(resource_name, resource_attribute)
  related_model = model.associations[resource_name][:model]
  related_association = related_model.associations[resource_attribute]

  if related_association
    self.define_delegation_for_related_association(resource_name, resource_attribute, related_association)
  else
    self.define_delegation_for_related_attribute(resource_name, resource_attribute)
  end
end
finalize_resource_delegates() click to toggle source
# File lib/praxis-mapper/resource.rb, line 88
def self.finalize_resource_delegates
  return unless @resource_delegates

  @resource_delegates.each do |record_name, record_attributes|
    record_attributes.each do |record_attribute|
      self.define_resource_delegate(record_name, record_attribute)
    end
  end
end
for_record(record) click to toggle source
# File lib/praxis-mapper/resource.rb, line 133
def self.for_record(record)
  return record._resource if record._resource

  if resource_class_for_record = model_map[record.class]
    return record._resource = resource_class_for_record.new(record)
  else
    version = self.name.split("::")[0..-2].join("::")
    resource_name = record.class.name.split("::").last

    raise "No resource class corresponding to the model class '#{record.class}' is defined. (Did you forget to define '#{version}::#{resource_name}'?)"
  end
end
get(condition) click to toggle source
# File lib/praxis-mapper/resource.rb, line 160
def self.get(condition)
  record = self.model.get(condition)

  self.wrap(record)
end
inherited(klass) click to toggle source

TODO: also support an attribute of sorts on the versioned resource module. ie, V1::Resources.api_version.

replacing the self.superclass == Praxis::Mapper::Resource condition below.
Calls superclass method
# File lib/praxis-mapper/resource.rb, line 42
def self.inherited(klass)
  super

  klass.instance_eval do
    # It is expected that each versioned set of resources
    # will have a common Base class, and so should share
    # a model_map
    if self.superclass == Praxis::Mapper::Resource
      @model_map = Hash.new
    else
      @model_map = self.superclass.model_map
    end

    @decorations = {}
    @properties = self.superclass.properties.clone
  end

end
model(klass=nil) click to toggle source

TODO: Take symbol/string and resolve the klass (but lazily, so we don't care about load order)

# File lib/praxis-mapper/resource.rb, line 62
def self.model(klass=nil)
  if klass
    @model = klass
    self.model_map[klass] = self
  else
    @model
  end
end
new(record) click to toggle source
# File lib/praxis-mapper/resource.rb, line 252
def initialize(record)
  @record = record
end
property(name, **options) click to toggle source
# File lib/praxis-mapper/resource.rb, line 76
def self.property(name, **options)
  self.properties[name] = options
end
resource_delegate(spec) click to toggle source
# File lib/praxis-mapper/resource.rb, line 177
def self.resource_delegate(spec)
  spec.each do |resource_name, attributes|
    resource_delegates[resource_name] = attributes
  end
end
resource_delegates() click to toggle source
# File lib/praxis-mapper/resource.rb, line 173
def self.resource_delegates
  @resource_delegates ||= {}
end
wrap(records) click to toggle source
# File lib/praxis-mapper/resource.rb, line 147
def self.wrap(records)
  if records.nil?
    return []
  elsif( records.is_a?(Enumerable) )
    return records.compact.map { |record| self.for_record(record) }
  elsif ( records.respond_to?(:to_a) )
    return records.to_a.compact.map { |record| self.for_record(record) }
  else
    return self.for_record(records)
  end
end

Public Instance Methods

method_missing(name,*args) click to toggle source
Calls superclass method
# File lib/praxis-mapper/resource.rb, line 260
def method_missing(name,*args)
  if @record.respond_to?(name)
    self.class.define_accessor(name)
    self.send(name)
  else
    super
  end
end
respond_to_missing?(name,*) click to toggle source
Calls superclass method
# File lib/praxis-mapper/resource.rb, line 256
def respond_to_missing?(name,*)
  @record.respond_to?(name) || super
end