diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index d66b2214cede1cef23b925f9b592e4572e5b4a73..17fcc2fa02a32e4404f63cc627997b43d9492ad5 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -3,12 +3,27 @@ module ImplicitRender 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 7aef8a50ce1b6f145cf2f077ee629bdbb02434a1..8591bdb4d9584e79092701e941285dec58bba349 100644 --- a/actionpack/test/controller/mime/respond_to_test.rb +++ b/actionpack/test/controller/mime/respond_to_test.rb @@ -793,3 +793,24 @@ def test_variant_negotiation_without_block 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