lib/spree/core/controller_helpers/respond_with.rb
# frozen_string_literal: true
require 'spree/responder'
module ActionController
class Base
def respond_with(*resources, &)
if self.class.mimes_for_respond_to.empty?
raise "In order to use respond_with, first you need to declare the formats your " \
"controller responds to in the class level"
end
return unless (collector = retrieve_collector_from_mimes(&))
options = resources.size == 1 ? {} : resources.extract_options!
# Fix spree issues #3531 and #2210 (patch provided by leiyangyou)
if (defined_response = collector.response) &&
!ApplicationController.spree_responders[self.class.to_s.to_sym].try(:[],
action_name.to_sym)
if action = options.delete(:action)
render(action:)
else
defined_response.call
end
else
# The action name is needed for processing
options[:action_name] = action_name.to_sym
# If responder is not specified then pass in Spree::Responder
(options.delete(:responder) || Spree::Responder).call(self, resources, options)
end
end
private
def retrieve_collector_from_mimes(mimes = nil, &block)
mimes ||= collect_mimes_from_class_level
collector = Collector.new(mimes, request.variant)
block.call(collector) if block_given?
format = collector.negotiate_format(request)
raise ActionController::UnknownFormat unless format
_process_format(format)
collector
end
end
end
module Spree
module Core
module ControllerHelpers
module RespondWith
extend ActiveSupport::Concern
included do
cattr_accessor :spree_responders
self.spree_responders = {}
end
module ClassMethods
def clear_overrides!
self.spree_responders = {}
end
def respond_override(options = {})
return if options.blank?
action_name = options.keys.first
action_value = options.values.first
if action_name.blank? || action_value.blank?
raise ArgumentError, "invalid values supplied #{options.inspect}"
end
format_name = action_value.keys.first
format_value = action_value.values.first
if format_name.blank? || format_value.blank?
raise ArgumentError, "invalid values supplied #{options.inspect}"
end
if format_value.is_a?(Proc)
options = {
action_name.to_sym => { format_name.to_sym => { success: format_value } }
}
end
spree_responders.deep_merge!(name.to_sym => options)
end
end
end
end
end
end