lib/alba/association.rb in alba-1.5.0 vs lib/alba/association.rb in alba-1.6.0

- old
+ new

@@ -1,39 +1,59 @@ module Alba - # Base class for `One` and `Many` - # Child class should implement `to_hash` method + # Representing association class Association + @const_cache = {} + class << self + attr_reader :const_cache + end + attr_reader :object, :name # @param name [Symbol, String] name of the method to fetch association # @param condition [Proc, nil] a proc filtering data # @param resource [Class<Alba::Resource>, nil] a resource class for the association # @param nesting [String] a namespace where source class is inferred with # @param block [Block] used to define resource when resource arg is absent def initialize(name:, condition: nil, resource: nil, nesting: nil, &block) @name = name @condition = condition - @block = block @resource = resource return if @resource - assign_resource(nesting) + assign_resource(nesting, block) end + # Recursively converts an object into a Hash + # + # @param target [Object] the object having an association method + # @param within [Hash] determines what associations to be serialized. If not set, it serializes all associations. + # @param params [Hash] user-given Hash for arbitrary data + # @return [Hash] + def to_h(target, within: nil, params: {}) + @object = target.public_send(@name) + @object = @condition.call(object, params) if @condition + return if @object.nil? + + @resource = constantize(@resource) + @resource.new(object, params: params, within: within).to_h + end + private def constantize(resource) case resource # rubocop:disable Style/MissingElse when Class resource when Symbol, String - Object.const_get(resource) + self.class.const_cache.fetch(resource) do + self.class.const_cache[resource] = Object.const_get(resource) + end end end - def assign_resource(nesting) - @resource = if @block - Alba.resource_class(&@block) + def assign_resource(nesting, block) + @resource = if block + Alba.resource_class(&block) elsif Alba.inferring Alba.infer_resource_class(@name, nesting: nesting) else raise ArgumentError, 'When Alba.inferring is false, either resource or block is required' end