aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Copeland <davetron5000@gmail.com>2015-05-29 07:34:19 -0500
committerDave Copeland <davetron5000@gmail.com>2015-06-20 12:00:07 -0400
commit6fda6c3778b27ea9ca70645bb65956154c2da27b (patch)
treeb66b520b57bf497a2b02ed7a08042a4f52ea07bd
parent068ab23a33b245d8f481bb839549806280effe48 (diff)
downloadrails-6fda6c3778b27ea9ca70645bb65956154c2da27b.tar.gz
rails-6fda6c3778b27ea9ca70645bb65956154c2da27b.tar.bz2
rails-6fda6c3778b27ea9ca70645bb65956154c2da27b.zip
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`.
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb19
-rw-r--r--actionpack/test/controller/mime/respond_to_test.rb21
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 <tt>new.html+phone.erb</tt> template.
+ #
+ # If no template is found <tt>ActionController::BasicImplicitRender</tt>'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