lib/alba/resource.rb in alba-3.0.3 vs lib/alba/resource.rb in alba-3.1.0
- old
+ new
@@ -20,11 +20,11 @@
# `setup` method is meta-programmatically defined here for performance.
# @private
def self.included(base) # rubocop:disable Metrics/MethodLength
super
- setup_method_body = 'private def _setup;'
+ setup_method_body = +'private def _setup;'
base.class_eval do
# Initialize
INTERNAL_VARIABLES.each do |name, initial|
instance_variable_set(:"@#{name}", initial.dup) unless instance_variable_defined?(:"@#{name}")
setup_method_body << "@#{name} = self.class.#{name};"
@@ -64,11 +64,18 @@
# The first options is a dummy parameter
#
# @see #serialize
# @see https://github.com/rails/rails/blob/7-0-stable/actionpack/lib/action_controller/metal/renderers.rb#L156
def to_json(options = {}, root_key: nil, meta: {})
- _to_json(root_key, meta, options)
+ confusing_options = options.keys.select { |k| k.to_sym == :only || k.to_sym == :except }
+ unless confusing_options.empty?
+ confusing_options.sort!
+ confusing_options.map! { |s| "\"#{s}\"" }
+ message = "You passed #{confusing_options.join(' and ')} options but ignored. Please refer to the document: https://github.com/okuramasafumi/alba/blob/main/docs/rails.md"
+ Kernel.warn(message)
+ end
+ serialize(root_key: root_key, meta: meta)
end
# Returns a Hash correspondng {#serialize}
#
# @param _options [Hash] dummy parameter for Rails compatibility
@@ -94,36 +101,34 @@
end
alias to_h serializable_hash
private
- def _to_json(root_key, meta, options)
- confusing_options = options.keys.select { |k| k.to_sym == :only || k.to_sym == :except }
- unless confusing_options.empty?
- confusing_options.sort!
- confusing_options.map! { |s| "\"#{s}\"" }
- message = "You passed #{confusing_options.join(' and ')} options but ignored. Please refer to the document: https://github.com/okuramasafumi/alba/blob/main/docs/rails.md"
- Kernel.warn(message)
- end
- serialize(root_key: root_key, meta: meta)
- end
-
def serialize_with(hash)
serialized_json = encode(hash)
return serialized_json unless @_layout
@_layout.serialize(resource: self, serialized_json: serialized_json, binding: binding)
end
def hash_with_metadata(hash, meta)
- return hash if meta.empty? && @_meta.nil?
+ return hash if meta.empty? && @_meta&.last.nil?
- metadata = @_meta ? instance_eval(&@_meta).merge(meta) : meta
- hash[:meta] = metadata
+ key, block = @_meta || :meta
+
+ if key
+ hash[key] = _metadata(block, meta)
+ else
+ _metadata(block, meta).each { |k, v| hash[k] = v }
+ end
hash
end
+ def _metadata(block, meta)
+ block ? instance_eval(&block).merge(meta) : meta
+ end
+
def serializable_hash_for_collection
if @_collection_key
@object.to_h do |item|
k = item.public_send(@_collection_key)
key = Alba.regularize_key(k)
@@ -210,18 +215,21 @@
hash[key] = value unless value == Alba::REMOVE_KEY
end
def handle_error(error, obj, key, attribute, hash)
- on_error = @_on_error || :raise
- case on_error # rubocop:disable Style/MissingElse
+ case (on_error = @_on_error || :raise)
when :raise, nil then raise(error)
when :nullify then hash[key] = nil
when :ignore then nil
when Proc
key, value = on_error.call(error, obj, key, attribute, self.class)
hash[key] = value
+ else
+ # :nocov:
+ raise Alba::Error, 'Impossible path'
+ # :nocov:
end
end
def transform_key(key)
return Alba.regularize_key(key) if @_transform_type == :none || key.nil? || key.empty? # We can skip transformation
@@ -231,15 +239,19 @@
Alba.regularize_key(_transform_key(inflector, key.to_s))
end
def _transform_key(inflector, key)
- case @_transform_type # rubocop:disable Style/MissingElse
+ case @_transform_type
when :camel then inflector.camelize(key)
when :lower_camel then inflector.camelize_lower(key)
when :dash then inflector.dasherize(key)
when :snake then inflector.underscore(key)
+ else
+ # :nocov:
+ raise Alba::Error, "Unknown transform type: #{@_transform_type}"
+ # :nocov:
end
end
def fetch_attribute(obj, key, attribute) # rubocop:disable Metrics/CyclomaticComplexity
value = case attribute
@@ -247,11 +259,13 @@
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, within: @within)
when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: obj) { |attr| fetch_attribute(obj, key, attr) }
+ # :nocov:
else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
+ # :nocov:
end
value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
end
def fetch_attribute_from_object_and_resource(obj, attribute)
@@ -264,15 +278,11 @@
__send__(attribute, obj)
end
def _fetch_attribute_from_resource_first(obj, attribute)
if @_resource_methods.include?(attribute)
- begin
- __send__(attribute, obj)
- rescue NoMethodError
- obj.__send__(attribute)
- end
+ __send__(attribute, obj)
else
obj.__send__(attribute)
end
end
@@ -443,11 +453,11 @@
@_key = true
@_key_for_collection = true
end
# Set metadata
- def meta(&block)
- @_meta = block
+ def meta(key = :meta, &block)
+ @_meta = [key, block]
end
# Set layout
#
# @param file [String] name of the layout file