lib/alba/resource.rb in alba-0.11.0 vs lib/alba/resource.rb in alba-0.11.1
- old
+ new
@@ -1,13 +1,18 @@
-require 'alba/serializer'
-require 'alba/one'
-require 'alba/many'
+require_relative 'serializer'
+require_relative 'one'
+require_relative 'many'
module Alba
# This module represents what should be serialized
module Resource
+ # @!parse include InstanceMethods
+ # @!parse extend ClassMethods
DSLS = {_attributes: {}, _serializer: nil, _key: nil}.freeze
+ private_constant :DSLS
+
+ # @private
def self.included(base)
super
base.class_eval do
# Initialize
DSLS.each do |name, initial|
@@ -20,16 +25,22 @@
# Instance methods
module InstanceMethods
attr_reader :object, :_key, :params
+ # @param object [Object] the object to be serialized
+ # @param params [Hash] user-given Hash for arbitrary data
def initialize(object, params: {})
@object = object
- @params = params
+ @params = params.freeze
DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.public_send(name)) }
end
+ # Get serializer with `with` argument and serialize self with it
+ #
+ # @param with [nil, Proc, Alba::Serializer] selializer
+ # @return [String] serialized JSON string
def serialize(with: nil)
serializer = case with
when nil
@_serializer || empty_serializer
when ->(obj) { obj.is_a?(Class) && obj <= Alba::Serializer }
@@ -40,15 +51,19 @@
raise ArgumentError, 'Unexpected type for with, possible types are Class or Proc'
end
serializer.new(self).serialize
end
+ # A Hash for serialization
+ #
+ # @return [Hash]
def serializable_hash
collection? ? @object.map(&converter) : converter.call(@object)
end
alias to_hash serializable_hash
+ # @return [Symbol]
def key
@_key || self.class.name.delete_suffix('Resource').downcase.gsub(/:{2}/, '_').to_sym
end
private
@@ -89,41 +104,75 @@
# Class methods
module ClassMethods
attr_reader(*DSLS.keys)
+ # @private
def inherited(subclass)
super
DSLS.each_key { |name| subclass.instance_variable_set("@#{name}", instance_variable_get("@#{name}").clone) }
end
+ # Set multiple attributes at once
+ #
+ # @param attrs [Array<String, Symbol>]
def attributes(*attrs)
attrs.each { |attr_name| @_attributes[attr_name.to_sym] = attr_name.to_sym }
end
+ # Set an attribute with the given block
+ #
+ # @param name [String, Symbol] key name
+ # @param block [Block] the block called during serialization
+ # @raise [ArgumentError] if block is absent
def attribute(name, &block)
raise ArgumentError, 'No block given in attribute method' unless block
@_attributes[name.to_sym] = block
end
+ # Set One association
+ #
+ # @param name [String, Symbol]
+ # @param condition [Proc]
+ # @param resource [Class<Alba::Resource>]
+ # @param key [String, Symbol] used as key when given
+ # @param block [Block]
+ # @see Alba::One#initialize
def one(name, condition = nil, resource: nil, key: nil, &block)
@_attributes[key&.to_sym || name.to_sym] = One.new(name: name, condition: condition, resource: resource, &block)
end
+ # Set Many association
+ #
+ # @param name [String, Symbol]
+ # @param condition [Proc]
+ # @param resource [Class<Alba::Resource>]
+ # @param key [String, Symbol] used as key when given
+ # @param block [Block]
+ # @see Alba::Many#initialize
def many(name, condition = nil, resource: nil, key: nil, &block)
@_attributes[key&.to_sym || name.to_sym] = Many.new(name: name, condition: condition, resource: resource, &block)
end
+ # Set serializer for the resource
+ #
+ # @param name [Alba::Serializer]
def serializer(name)
@_serializer = name <= Alba::Serializer ? name : nil
end
+ # Set key
+ #
+ # @param key [String, Symbol]
def key(key)
@_key = key.to_sym
end
+ # Delete attributes
# Use this DSL in child class to ignore certain attributes
+ #
+ # @param attributes [Array<String, Symbol>]
def ignoring(*attributes)
attributes.each do |attr_name|
@_attributes.delete(attr_name.to_sym)
end
end