lib/azeroth/decorator.rb in azeroth-0.1.0 vs lib/azeroth/decorator.rb in azeroth-0.2.0
- old
+ new
@@ -38,32 +38,37 @@
# # 'name' => 'John Wick',
# # 'age' => nil,
# # 'pokemon' => 'Arcanine'
# # }
class Decorator
+ autoload :HashBuilder, 'azeroth/decorator/hash_builder'
+
class << self
# @api private
#
# All attributes exposed
#
# @return [Array<Symbol>]
- def attributes
- @attributes ||= []
+ def attributes_map
+ @attributes_map ||= {}
end
private
- # rubocop:disable Naming/UncommunicativeMethodParamName
-
# @visibility public
# @api public
# @private
#
# Expose attributes on json decorated
#
# @param attribute [Symbol,String] attribute to be exposed
- # @param as [Symbol,String] name of the attribute on the json
+ # @param options [Hash] exposing options
+ # @option options as [Symbol,String] custom key
+ # to expose
+ # @option options if [Symbol,Proc] method/block to be called
+ # checking if an attribute should or should not
+ # be exposed
#
# @return [Array<Symbol>]
#
# @example
# class DummyModel
@@ -80,18 +85,17 @@
# def name
# [object.first_name, object.last_name].join(' ')
# end
# end
# end
- def expose(attribute, as: attribute)
+ def expose(attribute, **options)
builder = Sinclair.new(self)
- builder.add_method(as, "@object.#{attribute}")
+ builder.add_method(attribute, "@object.#{attribute}")
builder.build
- attributes << as.to_sym
+ attributes_map[attribute] = options
end
- # rubocop:enable Naming/UncommunicativeMethodParamName
end
# @api private
#
# @overload initialize(object)
@@ -107,21 +111,17 @@
# Builds hash / Json from the given object
#
# When object is an iterator, decoration is applied to each
# and an array is returned
#
- # @param *args [Hash] options (to be implemented)
+ # @param args [Hash] options (to be implemented)
#
# @return [Hash]
def as_json(*args)
return array_as_json(*args) if enum?
- {}.tap do |hash|
- self.class.attributes.each do |method|
- hash[method.to_s] = public_send(method)
- end
- end
+ HashBuilder.new(self).as_json
end
private
attr_reader :object
@@ -150,8 +150,43 @@
# @return [Array<Hash>]
def array_as_json(*args)
object.map do |item|
self.class.new(item).as_json(*args)
end
+ end
+
+ # @api private
+ # @private
+ # Method called when method is missing
+ #
+ # This delegates method calls to the given object
+ #
+ # @param method_name [Symbol] name of the method
+ # called
+ # @param args [Array<Object>] arguments of the
+ # method called
+ #
+ # @return [Object]
+ def method_missing(method_name, *args)
+ if object.respond_to?(method_name)
+ object.public_send(method_name, *args)
+ else
+ super
+ end
+ end
+
+ # @api private
+ # @private
+ # Checks if it would respond to a method
+ #
+ # The decision is delegated to the object
+ #
+ # @param method_name [Symbol] name of the method checked
+ # @param include_private [TrueClass,FalseClass] flag
+ # indicating if private methods should be included
+ #
+ # @return [TrueClass,FalseClass]
+ def respond_to_missing?(method_name, include_private)
+ object.respond_to?(method_name, include_private)
end
end
end