class ActiveRepresenter::Base

Action Representer Base

This is a base class for a representer (wrapped object). It wraps the original object as `wrapped` attribute and you can add custom methods to the class (using the decorator pattern).

In addition, `attr_field` / `attr_collection` can be used for attributes.

attr_field:

Declare additional field and type to the objects.
You can get / set field's value (converted to corresponding).
It uses ActiveModel::Attributes internally.
See examples: AttrFieldTest in test/attr_field_test.

attr_one:

Declare an associated object like has one association.
If a representer for the object is found, the object will be wrapped by the representer.
See examples: AttrOneTest in test/attr_one_test.

attr_many:

Declare associated objects like has many association.
If a representer for the objects is found, the objects will be wrapped by the representer.
See examples: AttrCollectionTest in test/attr_collection_test.

Public Class Methods

attr_collection(name, **options) click to toggle source
# File lib/active_representer/base.rb, line 100
def self.attr_collection(name, **options)
  check_name_type(name)
  representer_name = specify_or_guess_representer_name(options[:representer_name], name)

  begin
    representer = representer_name.constantize
    collections[name.to_sym] = representer
  rescue NameError
    collections[name.to_sym] = nil
  end

  class_eval do
    attr_reader name.to_sym
  end
end
attr_field(name, type = Type::Value.new, **options) click to toggle source
# File lib/active_representer/base.rb, line 80
def self.attr_field(name, type = Type::Value.new, **options)
  attribute(name, type, **options)
end
attr_one(name, **options) click to toggle source
# File lib/active_representer/base.rb, line 84
def self.attr_one(name, **options)
  check_name_type(name)
  representer_name = specify_or_guess_representer_name(options[:representer_name], name)

  begin
    representer = representer_name.constantize
    ones[name.to_sym] = representer
  rescue NameError
    ones[name.to_sym] = nil
  end

  class_eval do
    attr_reader name.to_sym
  end
end
attribute_names() click to toggle source
# File lib/active_representer/base.rb, line 126
def self.attribute_names
  attribute_types.keys - ["wrapped"]
end
check_name_type(name) click to toggle source
# File lib/active_representer/base.rb, line 130
def self.check_name_type(name)
  unless name.is_a?(Symbol) || name.is_a?(String)
    raise ArgumentError.new("collection's name must be a Symbol or a String")
  end
end
collection_names() click to toggle source
# File lib/active_representer/base.rb, line 122
def self.collection_names
  collections.keys
end
guess_representrer_name(name) click to toggle source
# File lib/active_representer/base.rb, line 136
def self.guess_representrer_name(name)
  "#{name.singularize.camelize}Representer"
end
inherited(subclass) click to toggle source
# File lib/active_representer/base.rb, line 40
def self.inherited(subclass)
  subclass.ones = {}
  subclass.collections = {}
end
one_names() click to toggle source
# File lib/active_representer/base.rb, line 118
def self.one_names
  ones.keys
end
specify_or_guess_representer_name(specified_name, wrapped_name) click to toggle source
# File lib/active_representer/base.rb, line 140
def self.specify_or_guess_representer_name(specified_name, wrapped_name)
  specified_name ? specified_name.to_s : guess_representrer_name(wrapped_name.to_s)
end
wrap(wrapped) click to toggle source
# File lib/active_representer/base.rb, line 45
def self.wrap(wrapped)
  instance = new
  instance.wrapped = wrapped

  one_names.each do |one_name|
    next if wrapped[one_name].nil?
    representer_klass = ones[one_name]
    one_value = \
      if representer_klass
        representer_klass.wrap(wrapped[one_name])
      else
        wrapped[one_name]
      end
    instance.instance_variable_set("@#{one_name}", one_value)
  end

  collection_names.each do |collection_name|
    next if wrapped[collection_name].nil?
    representer_klass = collections[collection_name]
    collection_value = \
      if representer_klass
        wrapped[collection_name].map { |item| representer_klass.wrap(item) }
      else
        wrapped[collection_name]
      end
    instance.instance_variable_set("@#{collection_name}", collection_value)
  end

  attribute_names.each do |attribute_name|
    instance.send("#{attribute_name}=", wrapped.send(attribute_name))
  end

  instance
end