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