lib/alba/resource.rb in alba-2.3.0 vs lib/alba/resource.rb in alba-2.4.0
- old
+ new
@@ -9,11 +9,11 @@
module Alba
# This module represents what should be serialized
module Resource
# @!parse include InstanceMethods
# @!parse extend ClassMethods
- DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _key_transformation_cascade: true, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil}.freeze # rubocop:disable Layout/LineLength
+ DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _key_transformation_cascade: true, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil, _helper: nil}.freeze # rubocop:disable Layout/LineLength
private_constant :DSLS
WITHIN_DEFAULT = Object.new.freeze
private_constant :WITHIN_DEFAULT
@@ -78,11 +78,11 @@
def to_json(options = {}, root_key: nil, meta: {})
_to_json(root_key, meta, options)
end
end
- # Returns a Hash correspondng {Resource#serialize}
+ # Returns a Hash correspondng {#serialize}
#
# @param root_key [Symbol, nil, true]
# @param meta [Hash] metadata for this seialization
# @return [Hash]
def as_json(root_key: nil, meta: {})
@@ -258,22 +258,32 @@
when Proc then instance_exec(obj, &attribute)
when Alba::Association then yield_if_within(attribute.name.to_sym) { |within| attribute.to_h(obj, params: params, within: within) }
when TypedAttribute then attribute.value(obj)
when NestedAttribute then attribute.value(object: obj, params: params)
when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: obj) { |attr| fetch_attribute(obj, key, attr) }
- else
- raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
+ else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
end
value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
end
+ # TODO: from version 3, `_fetch_attribute_from_resource_first` is default
def fetch_attribute_from_object_and_resource(obj, attribute)
+ _fetch_attribute_from_object_first(obj, attribute)
+ end
+
+ def _fetch_attribute_from_object_first(obj, attribute)
obj.__send__(attribute)
rescue NoMethodError
__send__(attribute, obj)
end
+ def _fetch_attribute_from_resource_first(obj, attribute)
+ __send__(attribute, obj)
+ rescue NoMethodError
+ obj.__send__(attribute)
+ end
+
def nil_handler
@_on_nil
end
def yield_if_within(association_name)
@@ -372,12 +382,11 @@
# @return [void]
# @see Alba::Association#initialize
def association(name, condition = nil, resource: nil, key: nil, params: {}, **options, &block)
key_transformation = @_key_transformation_cascade ? @_transform_type : :none
assoc = Association.new(
- name: name, condition: condition, resource: resource, params: params, nesting: nesting, key_transformation: key_transformation,
-&block
+ name: name, condition: condition, resource: resource, params: params, nesting: nesting, key_transformation: key_transformation, helper: @_helper, &block
)
@_attributes[key&.to_sym || name.to_sym] = options[:if] ? ConditionalAttribute.new(body: assoc, condition: options[:if]) : assoc
end
alias one association
alias many association
@@ -386,11 +395,11 @@
def nesting
if name.nil?
nil
else
- name.rpartition('::').first.tap { |n| n.empty? ? nil : n }
+ name.rpartition('::').first.then { |n| n.empty? ? nil : n }
end
end
private :nesting
# Set a nested attribute with the given block
@@ -500,9 +509,28 @@
# Set nil handler
#
# @param block [Block]
def on_nil(&block)
@_on_nil = block
+ end
+
+ # Define helper methods
+ #
+ # @param mod [Module] a module to extend
+ def helper(mod = @_helper || Module.new, &block)
+ mod.module_eval(&block) if block
+ extend mod
+ @_helper = mod
+ end
+
+ # DSL for alias, purely for readability
+ def prefer_resource_method!
+ alias_method :fetch_attribute_from_object_and_resource, :_fetch_attribute_from_resource_first
+ end
+
+ # DSL for alias, purely for readability
+ def prefer_object_method!
+ alias_method :fetch_attribute_from_object_and_resource, :_fetch_attribute_from_object_first
end
end
end
end