aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
authorErnie Miller <ernie@erniemiller.org>2012-08-26 15:37:23 -0400
committerErnie Miller <ernie@erniemiller.org>2012-09-03 13:13:17 -0400
commit05136e5c0b3d7b841bdec53847879321309604d3 (patch)
tree3a7c32f3e4a1c57be059a6c2a41381b41fa0b7cf /actionpack/lib/action_dispatch
parenteb43d3d1d94c67b3bf9c0cf576cdae8380f27260 (diff)
downloadrails-05136e5c0b3d7b841bdec53847879321309604d3.tar.gz
rails-05136e5c0b3d7b841bdec53847879321309604d3.tar.bz2
rails-05136e5c0b3d7b841bdec53847879321309604d3.zip
Make enhanced routing Concerns more tell-don't-ask
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb80
1 files changed, 55 insertions, 25 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 8573f4d80b..ddb34a2394 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1585,7 +1585,7 @@ module ActionDispatch
end
end
- # Routing Concerns allows you to declare common routes that can be reused
+ # Routing Concerns allow you to declare common routes that can be reused
# inside others resources and routes.
#
# concern :commentable do
@@ -1606,32 +1606,65 @@ module ActionDispatch
# concerns :commentable
# end
module Concerns
- # Define a routing concern using a name. If a second parameter is
- # supplied, it should respond to call, which will receive the mapper
- # as a parameter, allowing for customized behavior based on the current
- # scope.
+ # Define a routing concern using a name.
#
- # concern :commentable do
- # resources :comments
+ # Concerns may be defined inline, using a block, or handled by
+ # another object, by passing that object as the second parameter.
+ #
+ # The concern object, if supplied, should respond to <tt>call</tt>,
+ # which will receive two parameters:
+ #
+ # * The current mapper
+ # * A hash of options which the concern object may use
+ #
+ # Options may also be used by concerns defined in a block by accepting
+ # a block parameter. So, using a block, you might do something as
+ # simple as limit the actions available on certain resources, passing
+ # standard resource options through the concern:
+ #
+ # concern :commentable do |options|
+ # resources :comments, options
+ # end
+ #
+ # resources :posts, concerns: :commentable
+ # resources :archived_posts do
+ # # Don't allow comments on archived posts
+ # concerns :commentable, only: [:index, :show]
# end
#
- # # - or -
+ # Or, using a callable object, you might implement something more
+ # specific to your application, which would be out of place in your
+ # routes file.
#
- # class Commentable
- # def self.call(mapper)
- # if mapper.current_scope[:controller] == 'videos'
- # mapper.resources :video_comments, as: :comments
- # else
- # mapper.resources :comments
- # end
+ # # purchasable.rb
+ # class Purchasable
+ # def initialize(defaults = {})
+ # @defaults = defaults
+ # end
+ #
+ # def call(mapper, options = {})
+ # options = @defaults.merge(options)
+ # mapper.resources :purchases
+ # mapper.resources :receipts
+ # mapper.resources :returns if options[:returnable]
# end
# end
#
- # concern :commentable, Commentable
+ # # routes.rb
+ # concern :purchasable, Purchasable.new(returnable: true)
+ #
+ # resources :toys, concerns: :purchasable
+ # resources :electronics, concerns: :purchasable
+ # resources :pets do
+ # concerns :purchasable, returnable: false
+ # end
#
- # Any routing helpers can be used inside a concern.
+ # Any routing helpers can be used inside a concern. If using a
+ # callable, they're accessible from the Mapper that's passed to
+ # <tt>call</tt>.
def concern(name, callable = nil, &block)
- @concerns[name] = callable || lambda { |m| m.instance_eval(&block) }
+ callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) }
+ @concerns[name] = callable
end
# Use the named concerns
@@ -1645,10 +1678,11 @@ module ActionDispatch
# namespace :posts do
# concerns :commentable
# end
- def concerns(*names)
- names.flatten.each do |name|
+ def concerns(*args)
+ options = args.extract_options!
+ args.flatten.each do |name|
if concern = @concerns[name]
- concern.call(self)
+ concern.call(self, options)
else
raise ArgumentError, "No concern named #{name} was found!"
end
@@ -1662,10 +1696,6 @@ module ActionDispatch
@concerns = {}
end
- def current_scope
- @scope
- end
-
include Base
include HttpHelpers
include Redirection