aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorErnie Miller <ernie@erniemiller.org>2012-08-22 10:27:42 -0400
committerErnie Miller <ernie@erniemiller.org>2012-09-03 13:13:16 -0400
commit4037e31d8874250e485ca6a27bd792a3beb13f76 (patch)
tree448dc02534c5b9d5116bc0b11d19a56125873411 /actionpack
parent30a8f0d5b675d0eddc0af05103f4eb7f95c7caad (diff)
downloadrails-4037e31d8874250e485ca6a27bd792a3beb13f76.tar.gz
rails-4037e31d8874250e485ca6a27bd792a3beb13f76.tar.bz2
rails-4037e31d8874250e485ca6a27bd792a3beb13f76.zip
Allow routing concerns to accept a callable
This allows us to make alterations to the generated routes based on the scope of the current mapper, and otherwise allows us to move larger blocks of concerns out of the routes file, altogether.
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb10
-rw-r--r--actionpack/test/abstract_unit.rb1
-rw-r--r--actionpack/test/dispatch/routing/concerns_test.rb28
3 files changed, 34 insertions, 5 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index b52f66faf1..b1abbbe505 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1613,8 +1613,8 @@ module ActionDispatch
# end
#
# Any routing helpers can be used inside a concern.
- def concern(name, &block)
- @concerns[name] = block
+ def concern(name, callable = nil, &block)
+ @concerns[name] = callable || block
end
# Use the named concerns
@@ -1631,7 +1631,7 @@ module ActionDispatch
def concerns(*names)
names.flatten.each do |name|
if concern = @concerns[name]
- instance_eval(&concern)
+ concern.call(self)
else
raise ArgumentError, "No concern named #{name} was found!"
end
@@ -1645,6 +1645,10 @@ module ActionDispatch
@concerns = {}
end
+ def current_scope
+ @scope
+ end
+
include Base
include HttpHelpers
include Redirection
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index e5054a9eb8..4f5b2895c9 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -358,6 +358,7 @@ end
class ThreadsController < ResourcesController; end
class MessagesController < ResourcesController; end
class CommentsController < ResourcesController; end
+class ReviewsController < ResourcesController; end
class AuthorsController < ResourcesController; end
class LogosController < ResourcesController; end
diff --git a/actionpack/test/dispatch/routing/concerns_test.rb b/actionpack/test/dispatch/routing/concerns_test.rb
index 21da3bd77a..8600da32ad 100644
--- a/actionpack/test/dispatch/routing/concerns_test.rb
+++ b/actionpack/test/dispatch/routing/concerns_test.rb
@@ -1,6 +1,16 @@
require 'abstract_unit'
class RoutingConcernsTest < ActionDispatch::IntegrationTest
+ class Reviewable
+ def self.call(mapper)
+ if mapper.current_scope[:controller] == 'posts'
+ mapper.resources :reviews
+ elsif mapper.current_scope[:controller] == 'videos'
+ mapper.resources :reviews, as: :video_reviews
+ end
+ end
+ end
+
Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
app.draw do
concern :commentable do
@@ -11,8 +21,10 @@ class RoutingConcernsTest < ActionDispatch::IntegrationTest
resources :images, only: :index
end
- resources :posts, concerns: [:commentable, :image_attachable] do
- resource :video, concerns: :commentable
+ concern :reviewable, Reviewable
+
+ resources :posts, concerns: [:commentable, :image_attachable, :reviewable] do
+ resource :video, concerns: [:commentable, :reviewable]
end
resource :picture, concerns: :commentable do
@@ -63,6 +75,18 @@ class RoutingConcernsTest < ActionDispatch::IntegrationTest
assert_equal "404", @response.code
end
+ def test_accessing_callable_concern_from_resources
+ get "/posts/1/reviews/1"
+ assert_equal "200", @response.code
+ assert_equal "/posts/1/reviews/1", post_review_path(post_id: 1, id: 1)
+ end
+
+ def test_callable_concern_can_adapt_to_mapper
+ get "/posts/1/video/reviews/1"
+ assert_equal "200", @response.code
+ assert_equal "/posts/1/video/reviews/1", post_video_video_review_path(post_id: 1, id: 1)
+ end
+
def test_accessing_concern_from_a_scope
get "/videos/comments"
assert_equal "200", @response.code