1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Ensure shortcuts inside resources also generates helpers.

This commit is contained in:
José Valim 2010-08-24 14:54:23 -03:00
parent edba51cf33
commit 4a90ecb3ad
2 changed files with 43 additions and 52 deletions

View file

@ -43,9 +43,9 @@ module ActionDispatch
class Mapping #:nodoc:
IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix]
def initialize(set, scope, args)
@set, @scope = set, scope
@path, @options = extract_path_and_options(args)
def initialize(set, scope, path, options)
@set, @scope, @options = set, scope, options
@path = normalize_path(path)
normalize_options!
end
@ -54,31 +54,16 @@ module ActionDispatch
end
private
def extract_path_and_options(args)
options = args.extract_options!
if using_to_shorthand?(args, options)
path, to = options.find { |name, value| name.is_a?(String) }
options.merge!(:to => to).delete(path) if path
else
path = args.first
end
if path.match(':controller')
raise ArgumentError, ":controller segment is not allowed within a namespace block" if @scope[:module]
# Add a default constraint for :controller path segments that matches namespaced
# controllers with default routes like :controller/:action/:id(.:format), e.g:
# GET /admin/products/show/1
# => { :controller => 'admin/products', :action => 'show', :id => '1' }
options.reverse_merge!(:controller => /.+?/)
end
[ normalize_path(path), options ]
end
def normalize_options!
path_without_format = @path.sub(/\(\.:format\)$/, '')
@options = (@scope[:options] || {}).merge(@options)
if @scope[:as] && !@options[:as].blank?
@options[:as] = "#{@scope[:as]}_#{@options[:as]}"
elsif @scope[:as] && @options[:as] == ""
@options[:as] = @scope[:as].to_s
end
if using_match_shorthand?(path_without_format, @options)
to_shorthand = @options[:to].blank?
@ -89,11 +74,6 @@ module ActionDispatch
@options.merge!(default_controller_and_action(to_shorthand))
end
# match "account" => "account#index"
def using_to_shorthand?(args, options)
args.empty? && options.present?
end
# match "account/overview"
def using_match_shorthand?(path, options)
path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w\/]+$}
@ -101,7 +81,19 @@ module ActionDispatch
def normalize_path(path)
raise ArgumentError, "path is required" if @scope[:path].blank? && path.blank?
Mapper.normalize_path("#{@scope[:path]}/#{path}")
path = Mapper.normalize_path("#{@scope[:path]}/#{path}")
if path.match(':controller')
raise ArgumentError, ":controller segment is not allowed within a namespace block" if @scope[:module]
# Add a default constraint for :controller path segments that matches namespaced
# controllers with default routes like :controller/:action/:id(.:format), e.g:
# GET /admin/products/show/1
# => { :controller => 'admin/products', :action => 'show', :id => '1' }
@options.reverse_merge!(:controller => /.+?/)
end
path
end
def app
@ -233,8 +225,8 @@ module ActionDispatch
match '/', options.reverse_merge(:as => :root)
end
def match(*args)
mapping = Mapping.new(@set, @scope, args).to_route
def match(path, options=nil)
mapping = Mapping.new(@set, @scope, path, options || {}).to_route
@set.add_route(*mapping)
self
end
@ -389,21 +381,6 @@ module ActionDispatch
scope(:defaults => defaults) { yield }
end
def match(*args)
options = args.extract_options!
options = (@scope[:options] || {}).merge(options)
if @scope[:as] && !options[:as].blank?
options[:as] = "#{@scope[:as]}_#{options[:as]}"
elsif @scope[:as] && options[:as] == ""
options[:as] = @scope[:as].to_s
end
args.push(options)
super(*args)
end
private
def scope_options
@scope_options ||= private_methods.grep(/^merge_(.+)_scope$/) { $1.to_sym }
@ -957,10 +934,24 @@ module ActionDispatch
end
end
module Shorthand
def match(*args)
if args.size == 1 && args.last.is_a?(Hash)
options = args.pop
path, to = options.find { |name, value| name.is_a?(String) }
options.merge!(:to => to).delete(path)
super(path, options)
else
super
end
end
end
include Base
include HttpHelpers
include Scoping
include Resources
include Shorthand
end
end
end

View file

@ -203,9 +203,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
resources :customers do
get "recent" => "customers#recent", :as => :recent, :on => :collection
get "profile" => "customers#profile", :as => :profile, :on => :member
post "preview" => "customers#preview", :as => :preview, :on => :new
get "recent" => "customers#recent", :on => :collection
get "profile" => "customers#profile", :on => :member
post "preview" => "customers#preview", :as => :another_preview, :on => :new
resource :avatar do
get "thumbnail(.:format)" => "avatars#thumbnail", :as => :thumbnail, :on => :member
end
@ -1564,7 +1564,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
assert_equal '/customers/recent', recent_customers_path
assert_equal '/customers/1/profile', profile_customer_path(:id => '1')
assert_equal '/customers/new/preview', preview_new_customer_path
assert_equal '/customers/new/preview', another_preview_new_customer_path
assert_equal '/customers/1/avatar/thumbnail.jpg', thumbnail_customer_avatar_path(:customer_id => '1', :format => :jpg)
assert_equal '/customers/1/invoices/outstanding', outstanding_customer_invoices_path(:customer_id => '1')
assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')