Skip to content

Commit

Permalink
Allowed a 'render' arg that goes straight to the render call:
Browse files Browse the repository at this point in the history
- This new arg will go straight to the `render` call, it allows to pass any options allowed by rails `render` (like the http status or which template/file to render)
  • Loading branch information
Edouard-chin committed Mar 9, 2017
1 parent d7cb23b commit c44dd4f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
## Unreleased

* `respond_with` now accepts a new kwargs called `:render` which goes straight to the `render`
call after an unsuccessful post request. Usefull if for example you need to render a template
which is outside of controller's path eg:

`respond_with resource, render: { template: 'path/to/template' }`

## 2.3.0

* `verify_request_format!` is aliased to `verify_requested_format!` now.
Expand Down
8 changes: 7 additions & 1 deletion lib/action_controller/respond_with.rb
Expand Up @@ -182,11 +182,17 @@ def clear_respond_to
# to save a resource, e.g. when automatically rendering <tt>:new</tt>
# after a post request.
#
# Two additional options are relevant specifically to +respond_with+ -
# Three additional options are relevant specifically to +respond_with+ -
# 1. <tt>:location</tt> - overwrites the default redirect location used after
# a successful html +post+ request.
# 2. <tt>:action</tt> - overwrites the default render action used after an
# unsuccessful html +post+ request.
# 3. <tt>:render</tt> - allows to pass any options directly to the <tt>:render<tt/>
# call after unsuccessful html +post+ request. Usefull if for example you
# need to render a template which is outside of controller's path or you
# want to override the default http <tt>:status</tt> code, e.g.
#
# response_with(resource, render: { template: 'path/to/template', status: 422 })
def respond_with(*resources, &block)
if self.class.mimes_for_respond_to.empty?
raise "In order to use respond_with, first you need to declare the " \
Expand Down
10 changes: 9 additions & 1 deletion lib/action_controller/responder.rb
Expand Up @@ -200,7 +200,7 @@ def navigation_behavior(error)
if get?
raise error
elsif has_errors? && default_action
render :action => default_action
render rendering_options
else
redirect_to navigation_location
end
Expand Down Expand Up @@ -297,5 +297,13 @@ def json_resource_errors
def response_overridden?
@default_response.present?
end

def rendering_options
if options[:render]
options[:render]
else
{ action: default_action }
end
end
end
end
16 changes: 16 additions & 0 deletions test/action_controller/respond_with_test.rb
Expand Up @@ -66,6 +66,13 @@ def using_resource_with_action
end
end

def using_resource_with_rendering_options
rendering_options = { template: 'addresses/edit', status: :unprocessable_entity }
respond_with(resource, render: rendering_options) do |format|
format.html { raise ActionView::MissingTemplate.new([], "bar", ["foo"], {}, false) }
end
end

def using_responder_with_respond
responder = Class.new(ActionController::Responder) do
def respond; @controller.render :body => "respond #{format}"; end
Expand Down Expand Up @@ -482,6 +489,15 @@ def render(params={})
assert_equal "foo - #{[:html].to_s}", @controller.response.body
end

def test_using_resource_with_rendering_options
Customer.any_instance.stubs(:errors).returns(name: :invalid)

post :using_resource_with_rendering_options

assert_response :unprocessable_entity
assert_equal 'edit.html.erb', @controller.response.body
end

def test_respond_as_responder_entry_point
@request.accept = "text/html"
get :using_responder_with_respond
Expand Down

0 comments on commit c44dd4f

Please sign in to comment.