Class: ActiveRepresenter::Base

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model
Defined in:
lib/active_representer/base.rb

Overview

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.

Class Method Summary collapse

Class Method Details

.attr_collection(name, **options) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# 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) ⇒ Object



80
81
82
# 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) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 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_namesObject



126
127
128
# File 'lib/active_representer/base.rb', line 126

def self.attribute_names
  attribute_types.keys - ["wrapped"]
end

.check_name_type(name) ⇒ Object



130
131
132
133
134
# 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_namesObject



122
123
124
# File 'lib/active_representer/base.rb', line 122

def self.collection_names
  collections.keys
end

.guess_representrer_name(name) ⇒ Object



136
137
138
# File 'lib/active_representer/base.rb', line 136

def self.guess_representrer_name(name)
  "#{name.singularize.camelize}Representer"
end

.inherited(subclass) ⇒ Object



40
41
42
43
# File 'lib/active_representer/base.rb', line 40

def self.inherited(subclass)
  subclass.ones = {}
  subclass.collections = {}
end

.one_namesObject



118
119
120
# File 'lib/active_representer/base.rb', line 118

def self.one_names
  ones.keys
end

.specify_or_guess_representer_name(specified_name, wrapped_name) ⇒ Object



140
141
142
# 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) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 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