diff --git a/CHANGELOG.md b/CHANGELOG.md
index cbff77c..64deea0 100644
--- a/CHANGELOG.md
+++ b/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.
diff --git a/lib/action_controller/respond_with.rb b/lib/action_controller/respond_with.rb
index ebc988f..412d941 100644
--- a/lib/action_controller/respond_with.rb
+++ b/lib/action_controller/respond_with.rb
@@ -182,11 +182,17 @@ def clear_respond_to
# to save a resource, e.g. when automatically rendering :new
# after a post request.
#
- # Two additional options are relevant specifically to +respond_with+ -
+ # Three additional options are relevant specifically to +respond_with+ -
# 1. :location - overwrites the default redirect location used after
# a successful html +post+ request.
# 2. :action - overwrites the default render action used after an
# unsuccessful html +post+ request.
+ # 3. :render - allows to pass any options directly to the :render
+ # 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 :status 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 " \
diff --git a/lib/action_controller/responder.rb b/lib/action_controller/responder.rb
index a53bc64..3079289 100644
--- a/lib/action_controller/responder.rb
+++ b/lib/action_controller/responder.rb
@@ -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
@@ -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
diff --git a/test/action_controller/respond_with_test.rb b/test/action_controller/respond_with_test.rb
index 32a71d7..65e967f 100644
--- a/test/action_controller/respond_with_test.rb
+++ b/test/action_controller/respond_with_test.rb
@@ -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
@@ -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