lib/alba/resource.rb in alba-0.1.0 vs lib/alba/resource.rb in alba-0.2.0

- old
+ new

@@ -1,67 +1,101 @@ require 'alba/serializer' require 'alba/attribute' +require 'alba/one' +require 'alba/many' require 'alba/serializers/default_serializer' module Alba # This module represents what should be serialized module Resource + DSLS = [:_attributes, :_one, :_many, :_serializer].freeze def self.included(base) + base.class_eval do + # Initialize + DSLS.each do |name| + initial = name == :_serializer ? nil : {} + instance_variable_set("@#{name}", initial) unless instance_variable_defined?("@#{name}") + end + end base.include InstanceMethods base.extend ClassMethods end # Instance methods module InstanceMethods def initialize(resource) @_resource = resource - @_attributes = self.class._attributes - @_serializer_class = self.class._serializer_class + DSLS.each { |name| instance_variable_set("@#{name}", self.class.public_send(name)) } end def serialize(with: nil) - serializer_class = case with - when ->(obj) { obj.is_a?(Class) && obj.ancestors.include?(Alba::Serializer) } - with - when Symbol - const_get(with.to_s.capitalize) - when String - const_get(with) - when nil - @_serializer_class || Alba::Serializers::DefaultSerializer - end - # opts = serializer.opts - serialiable_hash = @_attributes.map do |name, attribute| - [name, attribute.serialize(@_resource)] - end.to_h - serializer_class.new(serialiable_hash).serialize + serializer = case with + when ->(obj) { obj.is_a?(Class) && obj <= Alba::Serializer } + with + when Symbol + const_get(with.to_s.capitalize) + when String + const_get(with) + when nil + @_serializer || Alba::Serializers::DefaultSerializer + end + serializer.new(serializable_hash).serialize end + + def serializable_hash + attrs.merge(ones).merge(manies) + end + alias to_hash serializable_hash + + private + + def attrs + @_attributes.transform_values do |attribute| + attribute.to_hash(@_resource) + end || {} + end + + def ones + @_one.transform_values do |one| + one.to_hash(@_resource) + end || {} + end + + def manies + @_many.transform_values do |many| + many.to_hash(@_resource) + end || {} + end end # Class methods module ClassMethods - attr_accessor :_attributes, :_serializer_class + attr_accessor(*DSLS) def inherited(subclass) - @_attributes = {} unless defined?(@_attributes) - @_serializer_class = nil unless defined?(@_serializer_class) - subclass._attributes = @_attributes - subclass._serializer_class = @_serializer_class + DSLS.each { |name| subclass.public_send("#{name}=", instance_variable_get("@#{name}")) } end def attributes(*attrs) - @_attributes = {} unless defined? @_attributes attrs.each { |attr_name| @_attributes[attr_name] = Attribute.new(name: attr_name, method: attr_name) } end def attribute(name, &block) raise ArgumentError, 'No block given in attribute method' unless block @_attributes[name] = Attribute.new(name: name, method: block) end + def one(name, resource: nil, &block) + @_one[name.to_sym] = One.new(name: name, resource: resource, &block) + end + + def many(name, resource: nil, &block) + @_many[name.to_sym] = Many.new(name: name, resource: resource, &block) + end + def serializer(name) - @_serializer_class = name.ancestors.include?(Alba::Serializer) ? name : nil + @_serializer = name <= Alba::Serializer ? name : nil end end end end