module Alba::Resource::InstanceMethods
Instance methods
Attributes
object[R]
params[R]
Public Class Methods
new(object, params: {}, within: WITHIN_DEFAULT)
click to toggle source
@param object [Object] the object to be serialized @param params [Hash] user-given Hash for arbitrary data @param within [Object, nil, false, true] determines what associations to be serialized. If not set, it serializes all associations.
# File lib/alba/resource.rb, line 37 def initialize(object, params: {}, within: WITHIN_DEFAULT) @object = object @params = params.freeze @within = within DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.public_send(name)) } end
Public Instance Methods
serializable_hash()
click to toggle source
A Hash for serialization
@return [Hash]
# File lib/alba/resource.rb, line 65 def serializable_hash collection? ? @object.map(&converter) : converter.call(@object) end
Also aliased as: to_hash
serialize(key: nil, root_key: nil, meta: {})
click to toggle source
Serialize object into JSON string
@param key [Symbol, nil, true] DEPRECATED, use root_key instead @param root_key [Symbol, nil, true] @param meta [Hash] metadata for this seialization @return [String] serialized JSON string
# File lib/alba/resource.rb, line 50 def serialize(key: nil, root_key: nil, meta: {}) warn '`key` option to `serialize` method is deprecated, use `root_key` instead.' if key key = key.nil? && root_key.nil? ? fetch_key : root_key || key hash = if key && key != '' h = {key.to_s => serializable_hash} hash_with_metadata(h, meta) else serializable_hash end Alba.encoder.call(hash) end
Private Instance Methods
_key()
click to toggle source
@return [String]
# File lib/alba/resource.rb, line 91 def _key return @_key.to_s unless @_key == true && Alba.inferring transforming_root_key? ? transform_key(resource_name) : resource_name end
_key_for_collection()
click to toggle source
# File lib/alba/resource.rb, line 83 def _key_for_collection return @_key_for_collection.to_s unless @_key_for_collection == true && Alba.inferring key = resource_name.pluralize transforming_root_key? ? transform_key(key) : key end
check_within(association_name)
click to toggle source
# File lib/alba/resource.rb, line 175 def check_within(association_name) case @within when WITHIN_DEFAULT then WITHIN_DEFAULT # Default value, doesn't check within tree when Hash then @within.fetch(association_name, nil) # Traverse within tree when Array then @within.find { |item| item.to_sym == association_name } when Symbol then @within == association_name when nil, true, false then false # Stop here else raise Alba::Error, "Unknown type for within option: #{@within.class}" end end
collection?()
click to toggle source
# File lib/alba/resource.rb, line 187 def collection? @object.is_a?(Enumerable) end
conditional_attribute(object, key, attribute)
click to toggle source
# File lib/alba/resource.rb, line 127 def conditional_attribute(object, key, attribute) condition = attribute.last arity = condition.arity # We can return early to skip fetch_attribute return [] if arity <= 1 && !instance_exec(object, &condition) fetched_attribute = fetch_attribute(object, attribute.first) attr = attribute.first.is_a?(Alba::Association) ? attribute.first.object : fetched_attribute return [] if arity >= 2 && !instance_exec(object, attr, &condition) [key, fetched_attribute] end
converter()
click to toggle source
# File lib/alba/resource.rb, line 105 def converter lambda do |object| arrays = @_attributes.map do |key, attribute| key_and_attribute_body_from(object, key, attribute) rescue ::Alba::Error, FrozenError, TypeError raise rescue StandardError => e handle_error(e, object, key, attribute) end arrays.reject(&:empty?).to_h end end
fetch_attribute(object, attribute)
click to toggle source
# File lib/alba/resource.rb, line 159 def fetch_attribute(object, attribute) case attribute when Symbol then object.public_send attribute when Proc then instance_exec(object, &attribute) when Alba::One, Alba::Many then yield_if_within(attribute.name.to_sym) { |within| attribute.to_hash(object, params: params, within: within) } when TypedAttribute then attribute.value(object) else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}" end end
fetch_key()
click to toggle source
# File lib/alba/resource.rb, line 79 def fetch_key collection? ? _key_for_collection : _key end
handle_error(error, object, key, attribute)
click to toggle source
# File lib/alba/resource.rb, line 140 def handle_error(error, object, key, attribute) on_error = @_on_error || Alba._on_error case on_error when :raise, nil then raise when :nullify then [key, nil] when :ignore then [] when Proc then on_error.call(error, object, key, attribute, self.class) else raise ::Alba::Error, "Unknown on_error: #{on_error.inspect}" end end
hash_with_metadata(hash, meta)
click to toggle source
# File lib/alba/resource.rb, line 72 def hash_with_metadata(hash, meta) base = @_meta ? instance_eval(&@_meta) : {} metadata = base.merge(meta) hash[:meta] = metadata unless metadata.empty? hash end
key_and_attribute_body_from(object, key, attribute)
click to toggle source
# File lib/alba/resource.rb, line 118 def key_and_attribute_body_from(object, key, attribute) key = transform_key(key) if attribute.is_a?(Array) # Conditional conditional_attribute(object, key, attribute) else [key, fetch_attribute(object, attribute)] end end
resource_name()
click to toggle source
# File lib/alba/resource.rb, line 97 def resource_name self.class.name.demodulize.delete_suffix('Resource').underscore end
transform_key(key)
click to toggle source
Override this method to supply custom key transform method
# File lib/alba/resource.rb, line 153 def transform_key(key) return key if @_transform_key_function.nil? @_transform_key_function.call(key.to_s) end
transforming_root_key?()
click to toggle source
# File lib/alba/resource.rb, line 101 def transforming_root_key? @_transforming_root_key.nil? ? Alba.transforming_root_key : @_transforming_root_key end
yield_if_within(association_name) { |within| ... }
click to toggle source
# File lib/alba/resource.rb, line 170 def yield_if_within(association_name) within = check_within(association_name) yield(within) if within end