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