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