Ensure that blocks are also handled inside the responder.
This commit is contained in:
parent
684a6b3c71
commit
3f78de67b5
@ -178,7 +178,10 @@ def clear_respond_to
|
||||
#
|
||||
def respond_to(*mimes, &block)
|
||||
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
||||
collect_mimes_for_render(mimes, block){ default_render }
|
||||
|
||||
if response = retrieve_response_from_mimes(mimes, &block)
|
||||
response.call
|
||||
end
|
||||
end
|
||||
|
||||
# respond_with wraps a resource around a responder for default representation.
|
||||
@ -211,8 +214,9 @@ def respond_to(*mimes, &block)
|
||||
# a proc to it.
|
||||
#
|
||||
def respond_with(*resources, &block)
|
||||
collect_mimes_for_render([], block) do
|
||||
if response = retrieve_response_from_mimes([], &block)
|
||||
options = resources.extract_options!
|
||||
options.merge!(:default_response => response)
|
||||
(options.delete(:responder) || responder).call(self, resources, options)
|
||||
end
|
||||
end
|
||||
@ -242,34 +246,29 @@ def collect_mimes_from_class_level #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
# Receives a collection of mimes and a block with formats and initialize a
|
||||
# collector. If a response was added to the collector, uses it to satisfy
|
||||
# the request, otherwise yields the block given.
|
||||
# Collects mimes and return the response for the negotiated format. Returns
|
||||
# nil if :not_acceptable was sent to the client.
|
||||
#
|
||||
def collect_mimes_for_render(mimes, formats)
|
||||
collector = Collector.new
|
||||
def retrieve_response_from_mimes(mimes, &block)
|
||||
collector = Collector.new { default_render }
|
||||
mimes = collect_mimes_from_class_level if mimes.empty?
|
||||
mimes.each { |mime| collector.send(mime) }
|
||||
formats.call(collector) if formats
|
||||
block.call(collector) if block_given?
|
||||
|
||||
if format = request.negotiate_mime(collector.order)
|
||||
self.formats = [format.to_sym]
|
||||
|
||||
if response = collector.response_for(format)
|
||||
response.call
|
||||
else
|
||||
yield
|
||||
end
|
||||
collector.response_for(format)
|
||||
else
|
||||
head :not_acceptable
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class Collector #:nodoc:
|
||||
attr_accessor :order
|
||||
|
||||
def initialize
|
||||
@order, @responses = [], {}
|
||||
def initialize(&block)
|
||||
@order, @responses, @default_response = [], {}, block
|
||||
end
|
||||
|
||||
def any(*args, &block)
|
||||
@ -283,13 +282,12 @@ def any(*args, &block)
|
||||
|
||||
def custom(mime_type, &block)
|
||||
mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
|
||||
|
||||
@order << mime_type
|
||||
@responses[mime_type] ||= block
|
||||
end
|
||||
|
||||
def response_for(mime)
|
||||
@responses[mime] || @responses[Mime::ALL]
|
||||
@responses[mime] || @responses[Mime::ALL] || @default_response
|
||||
end
|
||||
|
||||
def self.generate_method_for_mime(mime)
|
||||
|
@ -79,15 +79,16 @@ module ActionController #:nodoc:
|
||||
# Check polymorphic_url documentation for more examples.
|
||||
#
|
||||
class Responder
|
||||
attr_reader :controller, :request, :format, :resource, :resource_location, :options
|
||||
attr_reader :controller, :request, :format, :resource, :resources, :options
|
||||
|
||||
def initialize(controller, resources, options={})
|
||||
@controller = controller
|
||||
@request = controller.request
|
||||
@format = controller.formats.first
|
||||
@resource = resources.is_a?(Array) ? resources.last : resources
|
||||
@resource_location = options[:location] || resources
|
||||
@resources = resources
|
||||
@options = options
|
||||
@default_response = options.delete(:default_response)
|
||||
end
|
||||
|
||||
delegate :head, :render, :redirect_to, :to => :controller
|
||||
@ -109,7 +110,7 @@ def self.call(*args)
|
||||
# template.
|
||||
#
|
||||
def to_html
|
||||
render
|
||||
default_render
|
||||
rescue ActionView::MissingTemplate
|
||||
if get?
|
||||
raise
|
||||
@ -125,7 +126,7 @@ def to_html
|
||||
# responds to :to_format and display it.
|
||||
#
|
||||
def to_format
|
||||
render
|
||||
default_render
|
||||
rescue ActionView::MissingTemplate
|
||||
raise unless resourceful?
|
||||
|
||||
@ -148,6 +149,20 @@ def resourceful?
|
||||
resource.respond_to?(:"to_#{format}")
|
||||
end
|
||||
|
||||
# Returns the resource location by retrieving it from the options or
|
||||
# returning the resources array.
|
||||
#
|
||||
def resource_location
|
||||
options[:location] || resources
|
||||
end
|
||||
|
||||
# If a given response block was given, use it, otherwise call render on
|
||||
# controller.
|
||||
#
|
||||
def default_render
|
||||
@default_response.call
|
||||
end
|
||||
|
||||
# display is just a shortcut to render a resource with the current format.
|
||||
#
|
||||
# display @user, :status => :ok
|
||||
@ -166,7 +181,7 @@ def resourceful?
|
||||
# render :xml => @user, :status => :created
|
||||
#
|
||||
def display(resource, given_options={})
|
||||
render given_options.merge!(options).merge!(format => resource)
|
||||
controller.render given_options.merge!(options).merge!(format => resource)
|
||||
end
|
||||
|
||||
# Check if the resource has errors or not.
|
||||
|
@ -726,6 +726,13 @@ def test_first_in_respond_to_has_higher_priority
|
||||
assert_equal "<name>david</name>", @response.body
|
||||
end
|
||||
|
||||
def test_block_inside_respond_with_is_rendered
|
||||
@controller = InheritedRespondWithController.new
|
||||
@request.accept = "application/json"
|
||||
get :index
|
||||
assert_equal "JSON", @response.body
|
||||
end
|
||||
|
||||
def test_no_double_render_is_raised
|
||||
@request.accept = "text/html"
|
||||
assert_raise ActionView::MissingTemplate do
|
||||
|
Loading…
Reference in New Issue
Block a user