From 6fda6c3778b27ea9ca70645bb65956154c2da27b Mon Sep 17 00:00:00 2001 From: Dave Copeland Date: Fri, 29 May 2015 07:34:19 -0500 Subject: [PATCH] Override default_render's behavior with a block In 0de4a23 the behavior when there is a missing template was changed to not raise an error, but instead head :no_content. This is a breaking change and some gems rely on this happening. To allow gems and other code to work around this, allow `default_render` to take a block which, if provided, will execute the contents of that block instead of doing the `head :no_content`. --- .../metal/implicit_render.rb | 19 +++++++++++++++-- .../test/controller/mime/respond_to_test.rb | 21 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index d66b2214ce..17fcc2fa02 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -3,12 +3,27 @@ module ActionController include BasicImplicitRender + # Renders the template corresponding to the controller action, if it exists. + # The action name, format, and variant are all taken into account. + # For example, the "new" action with an HTML format and variant "phone" + # would try to render the new.html+phone.erb template. + # + # If no template is found ActionController::BasicImplicitRender's implementation is called, unless + # a block is passed. In that case, it will override the super implementation. + # + # default_render do + # head 404 # No template was found + # end def default_render(*args) if template_exists?(action_name.to_s, _prefixes, variants: request.variant) render(*args) else - logger.info "No template found for #{self.class.name}\##{action_name}, rendering head :no_content" if logger - super + if block_given? + yield(*args) + else + logger.info "No template found for #{self.class.name}\##{action_name}, rendering head :no_content" if logger + super + end end end diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb index 7aef8a50ce..8591bdb4d9 100644 --- a/actionpack/test/controller/mime/respond_to_test.rb +++ b/actionpack/test/controller/mime/respond_to_test.rb @@ -793,3 +793,24 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "phone", @response.body end end + +class RespondToWithBlockOnDefaultRenderController < ActionController::Base + def show + default_render do + render text: 'default_render yielded' + end + end +end + +class RespondToWithBlockOnDefaultRenderControllerTest < ActionController::TestCase + def setup + super + @request.host = "www.example.com" + end + + def test_default_render_uses_block_when_no_template_exists + get :show + assert_equal "default_render yielded", @response.body + assert_equal "text/html", @response.content_type + end +end