Permalink
Browse files

Merge pull request #79 from fnando/location-responder

Allow callable objects as the location
  • Loading branch information...
2 parents 9357c73 + 5c72d59 commit 040a39e065c969c1363b6f81b6cc57df3e401d13 @carlosantoniodasilva carlosantoniodasilva committed May 21, 2014
Showing with 105 additions and 14 deletions.
  1. +1 −0 CHANGELOG.md
  2. +14 −14 Gemfile.lock
  3. +18 −0 README.md
  4. +1 −0 lib/responders.rb
  5. +26 −0 lib/responders/location_responder.rb
  6. +44 −0 test/location_responder_test.rb
  7. +1 −0 test/views/locations/new.html.erb
View
@@ -1,6 +1,7 @@
## Unreleased
* Support Rails 4.1.
+* Allow callable objects as the location.
## 1.0.0
View
@@ -7,19 +7,19 @@ PATH
GEM
remote: https://rubygems.org/
specs:
- actionpack (4.1.0)
- actionview (= 4.1.0)
- activesupport (= 4.1.0)
+ actionpack (4.1.1)
+ actionview (= 4.1.1)
+ activesupport (= 4.1.1)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
- actionview (4.1.0)
- activesupport (= 4.1.0)
+ actionview (4.1.1)
+ activesupport (= 4.1.1)
builder (~> 3.1)
erubis (~> 2.7.0)
- activemodel (4.1.0)
- activesupport (= 4.1.0)
+ activemodel (4.1.1)
+ activesupport (= 4.1.1)
builder (~> 3.1)
- activesupport (4.1.0)
+ activesupport (4.1.1)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
@@ -30,18 +30,18 @@ GEM
i18n (0.6.9)
json (1.8.1)
metaclass (0.0.4)
- minitest (5.3.3)
- mocha (1.0.0)
+ minitest (5.3.4)
+ mocha (1.1.0)
metaclass (~> 0.0.1)
rack (1.5.2)
rack-test (0.6.2)
rack (>= 1.0)
- railties (4.1.0)
- actionpack (= 4.1.0)
- activesupport (= 4.1.0)
+ railties (4.1.1)
+ actionpack (= 4.1.1)
+ activesupport (= 4.1.1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
- rake (10.3.1)
+ rake (10.3.2)
thor (0.19.1)
thread_safe (0.3.3)
tzinfo (1.1.0)
View
@@ -60,6 +60,24 @@ You can also have embedded HTML. Just create a `_html` scope.
See also the `namespace_lookup` option to search the full hierarchy of possible keys.
+### Location Responder
+
+This responder allows you to use callable objects as the redirect location.
+Useful when you want to use the `respond_with` method with
+a custom route that requires persisted objects, but the validation may fail.
+
+```ruby
+class ThingsController < ApplicationController
+ responders :location, :flash
+ respond_to :html
+
+ def create
+ @thing = Things.create(params[:thing])
+ respond_with @thing, location: -> { thing_path(@thing) }
+ end
+end
+```
+
### HttpCacheResponder
Automatically adds Last-Modified headers to API requests. This
View
@@ -4,6 +4,7 @@ module Responders
autoload :FlashResponder, 'responders/flash_responder'
autoload :HttpCacheResponder, 'responders/http_cache_responder'
autoload :CollectionResponder, 'responders/collection_responder'
+ autoload :LocationResponder, 'responders/location_responder'
require 'responders/controller_method'
@@ -0,0 +1,26 @@
+module Responders
+ # Responder to accept callable objects as the redirect location.
+ # Useful when you want to use the <tt>respond_with</tt> method with
+ # a route that requires persisted objects, but the validation may fail.
+ #
+ # class ThingsController < ApplicationController
+ # responders :location, :flash
+ # respond_to :html
+ #
+ # def create
+ # @thing = Things.create(params[:thing])
+ # respond_with @thing, location: -> { thing_path(@thing) }
+ # end
+ # end
+ #
+ module LocationResponder
+ def initialize(controller, resources, options = {})
+ super
+
+ if options[:location].respond_to?(:call)
+ location = options.delete(:location)
+ options[:location] = location.call unless has_errors?
+ end
+ end
+ end
+end
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+class LocationResponder < ActionController::Responder
+ include Responders::LocationResponder
+end
+
+class LocationsController < ApplicationController
+ self.responder = LocationResponder
+
+ respond_to :html
+ before_filter :set_resource
+
+ def create
+ respond_with @resource, location: -> { 'given_location' }
+ end
+
+ def update
+ respond_with @resource, location: 'given_location'
+ end
+
+ def set_resource
+ @resource = Address.new
+ @resource.errors[:fail] << "FAIL" if params[:fail]
+ end
+end
+
+class LocationResponderTest < ActionController::TestCase
+ tests LocationsController
+
+ def test_redirects_to_block_location_on_success
+ post :create
+ assert_redirected_to 'given_location'
+ end
+
+ def test_renders_page_on_fail
+ post :create, fail: true
+ assert @response.body.include?('new.html.erb')
+ end
+
+ def test_redirects_to_plain_string
+ post :update
+ assert_redirected_to 'given_location'
+ end
+end
@@ -0,0 +1 @@
+new.html.erb

0 comments on commit 040a39e

Please sign in to comment.