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:
parent
edba51cf33
commit
4a90ecb3ad
2 changed files with 43 additions and 52 deletions
|
@ -43,9 +43,9 @@ module ActionDispatch
|
||||||
class Mapping #:nodoc:
|
class Mapping #:nodoc:
|
||||||
IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix]
|
IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix]
|
||||||
|
|
||||||
def initialize(set, scope, args)
|
def initialize(set, scope, path, options)
|
||||||
@set, @scope = set, scope
|
@set, @scope, @options = set, scope, options
|
||||||
@path, @options = extract_path_and_options(args)
|
@path = normalize_path(path)
|
||||||
normalize_options!
|
normalize_options!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,31 +54,16 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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!
|
def normalize_options!
|
||||||
path_without_format = @path.sub(/\(\.:format\)$/, '')
|
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)
|
if using_match_shorthand?(path_without_format, @options)
|
||||||
to_shorthand = @options[:to].blank?
|
to_shorthand = @options[:to].blank?
|
||||||
|
@ -89,11 +74,6 @@ module ActionDispatch
|
||||||
@options.merge!(default_controller_and_action(to_shorthand))
|
@options.merge!(default_controller_and_action(to_shorthand))
|
||||||
end
|
end
|
||||||
|
|
||||||
# match "account" => "account#index"
|
|
||||||
def using_to_shorthand?(args, options)
|
|
||||||
args.empty? && options.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
# match "account/overview"
|
# match "account/overview"
|
||||||
def using_match_shorthand?(path, options)
|
def using_match_shorthand?(path, options)
|
||||||
path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w\/]+$}
|
path && options.except(:via, :anchor, :to, :as).empty? && path =~ %r{^/[\w\/]+$}
|
||||||
|
@ -101,7 +81,19 @@ module ActionDispatch
|
||||||
|
|
||||||
def normalize_path(path)
|
def normalize_path(path)
|
||||||
raise ArgumentError, "path is required" if @scope[:path].blank? && path.blank?
|
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
|
end
|
||||||
|
|
||||||
def app
|
def app
|
||||||
|
@ -233,8 +225,8 @@ module ActionDispatch
|
||||||
match '/', options.reverse_merge(:as => :root)
|
match '/', options.reverse_merge(:as => :root)
|
||||||
end
|
end
|
||||||
|
|
||||||
def match(*args)
|
def match(path, options=nil)
|
||||||
mapping = Mapping.new(@set, @scope, args).to_route
|
mapping = Mapping.new(@set, @scope, path, options || {}).to_route
|
||||||
@set.add_route(*mapping)
|
@set.add_route(*mapping)
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
@ -389,21 +381,6 @@ module ActionDispatch
|
||||||
scope(:defaults => defaults) { yield }
|
scope(:defaults => defaults) { yield }
|
||||||
end
|
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
|
private
|
||||||
def scope_options
|
def scope_options
|
||||||
@scope_options ||= private_methods.grep(/^merge_(.+)_scope$/) { $1.to_sym }
|
@scope_options ||= private_methods.grep(/^merge_(.+)_scope$/) { $1.to_sym }
|
||||||
|
@ -957,10 +934,24 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
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 Base
|
||||||
include HttpHelpers
|
include HttpHelpers
|
||||||
include Scoping
|
include Scoping
|
||||||
include Resources
|
include Resources
|
||||||
|
include Shorthand
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -203,9 +203,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :customers do
|
resources :customers do
|
||||||
get "recent" => "customers#recent", :as => :recent, :on => :collection
|
get "recent" => "customers#recent", :on => :collection
|
||||||
get "profile" => "customers#profile", :as => :profile, :on => :member
|
get "profile" => "customers#profile", :on => :member
|
||||||
post "preview" => "customers#preview", :as => :preview, :on => :new
|
post "preview" => "customers#preview", :as => :another_preview, :on => :new
|
||||||
resource :avatar do
|
resource :avatar do
|
||||||
get "thumbnail(.:format)" => "avatars#thumbnail", :as => :thumbnail, :on => :member
|
get "thumbnail(.:format)" => "avatars#thumbnail", :as => :thumbnail, :on => :member
|
||||||
end
|
end
|
||||||
|
@ -1564,7 +1564,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
|
||||||
with_test_routes do
|
with_test_routes do
|
||||||
assert_equal '/customers/recent', recent_customers_path
|
assert_equal '/customers/recent', recent_customers_path
|
||||||
assert_equal '/customers/1/profile', profile_customer_path(:id => '1')
|
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/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/outstanding', outstanding_customer_invoices_path(:customer_id => '1')
|
||||||
assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')
|
assert_equal '/customers/1/invoices/2/print', print_customer_invoice_path(:customer_id => '1', :id => '2')
|
||||||
|
|
Loading…
Reference in a new issue