Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
2b7256a4
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2b7256a4
编写于
12月 24, 2009
作者:
D
David Heinemeier Hansson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Extract Mapping class from monster match method
上级
74b2e00c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
149 addition
and
91 deletion
+149
-91
actionpack/lib/action_dispatch/routing/mapper.rb
actionpack/lib/action_dispatch/routing/mapper.rb
+137
-90
actionpack/test/dispatch/routing_test.rb
actionpack/test/dispatch/routing_test.rb
+12
-1
未找到文件。
actionpack/lib/action_dispatch/routing/mapper.rb
浏览文件 @
2b7256a4
...
...
@@ -19,9 +19,9 @@ def call(env)
@constraints
.
each
{
|
constraint
|
if
constraint
.
respond_to?
(
:matches?
)
&&
!
constraint
.
matches?
(
req
)
return
[
417
,
{},
[]
]
return
[
417
,
{},
[]
]
elsif
constraint
.
respond_to?
(
:call
)
&&
!
constraint
.
call
(
req
)
return
[
417
,
{},
[]
]
return
[
417
,
{},
[]
]
end
}
...
...
@@ -29,94 +29,138 @@ def call(env)
end
end
module
Base
def
initialize
(
set
)
@set
=
set
class
Mapping
def
initialize
(
set
,
scope
,
args
)
@set
,
@scope
=
set
,
scope
@path
,
@options
=
extract_path_and_options
(
args
)
end
def
root
(
options
=
{})
match
'/'
,
options
.
merge
(
:as
=>
:root
)
def
to_route
[
app
,
conditions
,
requirements
,
defaults
,
@options
[
:as
]
]
end
def
match
(
*
args
)
if
args
.
one?
&&
args
.
first
.
is_a?
(
Hash
)
path
=
args
.
first
.
keys
.
first
options
=
{
:to
=>
args
.
first
.
values
.
first
}
else
path
=
args
.
first
private
def
extract_path_and_options
(
args
)
options
=
args
.
extract_options!
end
conditions
,
defaults
=
{},
{}
path
=
nil
if
path
==
""
path
=
"
#{
@scope
[
:path
]
}#{
path
}
"
if
@scope
[
:path
]
path
=
Rack
::
Mount
::
Utils
.
normalize_path
(
path
)
if
path
raise
ArgumentError
,
"path is required"
unless
path
constraints
=
options
[
:constraints
]
||
{}
unless
constraints
.
is_a?
(
Hash
)
block
,
constraints
=
constraints
,
{}
if
args
.
empty?
path
,
to
=
options
.
find
{
|
name
,
value
|
name
.
is_a?
(
String
)
}
options
.
merge!
(
:to
=>
to
).
delete
(
path
)
if
path
else
path
=
args
.
first
end
[
normalize_path
(
path
),
options
]
end
blocks
=
((
@scope
[
:blocks
]
||
[])
+
[
block
]).
compact
constraints
=
(
@scope
[
:constraints
]
||
{}).
merge
(
constraints
)
options
.
each
{
|
k
,
v
|
constraints
[
k
]
=
v
if
v
.
is_a?
(
Regexp
)
}
conditions
[
:path_info
]
=
path
requirements
=
constraints
.
dup
def
normalize_path
(
path
)
path
=
nil
if
path
==
""
path
=
"
#{
@scope
[
:path
]
}#{
path
}
"
if
@scope
[
:path
]
path
=
Rack
::
Mount
::
Utils
.
normalize_path
(
path
)
if
path
path_regexp
=
Rack
::
Mount
::
Strexp
.
compile
(
path
,
constraints
,
SEPARATORS
)
segment_keys
=
Rack
::
Mount
::
RegexpWithNamedGroups
.
new
(
path_regexp
).
names
constraints
.
reject!
{
|
k
,
v
|
segment_keys
.
include?
(
k
.
to_s
)
}
conditions
.
merge!
(
constraints
)
raise
ArgumentError
,
"path is required"
unless
path
path
end
requirements
[
:controller
]
||=
@set
.
controller_constraints
if
via
=
options
[
:via
]
via
=
Array
(
via
).
map
{
|
m
|
m
.
to_s
.
upcase
}
conditions
[
:request_method
]
=
Regexp
.
union
(
*
via
)
def
app
Constraints
.
new
(
to
.
respond_to?
(
:call
)
?
to
:
Routing
::
RouteSet
::
Dispatcher
.
new
(
:defaults
=>
defaults
),
blocks
)
end
defaults
[
:controller
]
||=
@scope
[
:controller
].
to_s
if
@scope
[
:controller
]
app
=
initialize_app_endpoint
(
options
,
defaults
)
validate_defaults!
(
app
,
defaults
,
segment_keys
)
app
=
Constraints
.
new
(
app
,
blocks
)
def
conditions
{
:path_info
=>
@path
}.
merge
(
constraints
).
merge
(
request_method_condition
)
end
def
requirements
@requirements
||=
returning
(
@options
[
:constraints
]
||
{})
do
|
requirements
|
requirements
.
reverse_merge!
(
@scope
[
:constraints
])
if
@scope
[
:constraints
]
@options
.
each
{
|
k
,
v
|
requirements
[
k
]
=
v
if
v
.
is_a?
(
Regexp
)
}
requirements
[
:controller
]
||=
@set
.
controller_constraints
end
end
@set
.
add_route
(
app
,
conditions
,
requirements
,
defaults
,
options
[
:as
])
def
defaults
@defaults
||=
if
to
.
respond_to?
(
:call
)
{
}
else
defaults
=
case
to
when
String
controller
,
action
=
to
.
split
(
'#'
)
{
:controller
=>
controller
,
:action
=>
action
}
when
Symbol
{
:controller
=>
default_controller
,
:action
=>
to
.
to_s
}
else
{
:controller
=>
default_controller
}
end
if
defaults
[
:controller
].
blank?
&&
segment_keys
.
exclude?
(
"controller"
)
raise
ArgumentError
,
"missing :controller"
end
if
defaults
[
:action
].
blank?
&&
segment_keys
.
exclude?
(
"action"
)
raise
ArgumentError
,
"missing :action"
end
defaults
end
end
self
end
def
blocks
if
@options
[
:constraints
].
present?
&&
!
@options
[
:constraints
].
is_a?
(
Hash
)
block
=
@options
[
:constraints
]
else
block
=
nil
end
((
@scope
[
:blocks
]
||
[])
+
[
block
]).
compact
end
def
constraints
@constraints
||=
requirements
.
reject
{
|
k
,
v
|
segment_keys
.
include?
(
k
.
to_s
)
||
k
==
:controller
}
end
private
def
initialize_app_endpoint
(
options
,
defaults
)
app
=
nil
if
options
[
:to
].
respond_to?
(
:call
)
app
=
options
[
:to
]
defaults
.
delete
(
:controller
)
defaults
.
delete
(
:action
)
elsif
options
[
:to
].
is_a?
(
String
)
defaults
[
:controller
],
defaults
[
:action
]
=
options
[
:to
].
split
(
'#'
)
elsif
options
[
:to
].
is_a?
(
Symbol
)
defaults
[
:action
]
=
options
[
:to
].
to_s
def
request_method_condition
if
via
=
@options
[
:via
]
via
=
Array
(
via
).
map
{
|
m
|
m
.
to_s
.
upcase
}
{
:request_method
=>
Regexp
.
union
(
*
via
)
}
else
{
}
end
end
def
segment_keys
@segment_keys
||=
Rack
::
Mount
::
RegexpWithNamedGroups
.
new
(
Rack
::
Mount
::
Strexp
.
compile
(
@path
,
requirements
,
SEPARATORS
)
).
names
end
app
||
Routing
::
RouteSet
::
Dispatcher
.
new
(
:defaults
=>
defaults
)
def
to
@options
[
:to
]
end
def
default_controller
@scope
[
:controller
].
to_s
if
@scope
[
:controller
]
end
end
def
validate_defaults!
(
app
,
defaults
,
segment_keys
)
return
unless
app
.
is_a?
(
Routing
::
RouteSet
::
Dispatcher
)
module
Base
def
initialize
(
set
)
@set
=
set
end
unless
defaults
.
include?
(
:controller
)
||
segment_keys
.
include?
(
"controller"
)
raise
ArgumentError
,
"missing :controller"
end
def
root
(
options
=
{}
)
match
'/'
,
options
.
reverse_merge
(
:as
=>
:root
)
end
unless
defaults
.
include?
(
:action
)
||
segment_keys
.
include?
(
"action"
)
raise
ArgumentError
,
"missing :action"
end
end
def
match
(
*
args
)
@set
.
add_route
(
*
Mapping
.
new
(
@set
,
@scope
,
args
).
to_route
)
self
end
end
module
HttpHelpers
...
...
@@ -139,15 +183,16 @@ def delete(*args, &block)
def
redirect
(
*
args
,
&
block
)
options
=
args
.
last
.
is_a?
(
Hash
)
?
args
.
pop
:
{}
path
=
args
.
shift
||
block
path_proc
=
path
.
is_a?
(
Proc
)
?
path
:
proc
{
|
params
|
path
%
params
}
status
=
options
[
:status
]
||
301
path
=
args
.
shift
||
block
path_proc
=
path
.
is_a?
(
Proc
)
?
path
:
proc
{
|
params
|
path
%
params
}
status
=
options
[
:status
]
||
301
lambda
do
|
env
|
req
=
Rack
::
Request
.
new
(
env
)
req
=
Rack
::
Request
.
new
(
env
)
params
=
path_proc
.
call
(
env
[
"action_dispatch.request.path_parameters"
])
url
=
req
.
scheme
+
'://'
+
req
.
host
+
params
[
status
,
{
'Location'
=>
url
,
'Content-Type'
=>
'text/html'
},
[
'Moved Permanently'
]]
url
=
req
.
scheme
+
'://'
+
req
.
host
+
params
[
status
,
{
'Location'
=>
url
,
'Content-Type'
=>
'text/html'
},
[
'Moved Permanently'
]
]
end
end
...
...
@@ -211,11 +256,11 @@ def scope(*args)
self
ensure
@scope
[
:path
]
=
path
if
path_set
@scope
[
:path
]
=
path
if
path_set
@scope
[
:name_prefix
]
=
name_prefix
if
name_prefix_set
@scope
[
:controller
]
=
controller
if
controller_set
@scope
[
:options
]
=
options
@scope
[
:blocks
]
=
blocks
@scope
[
:controller
]
=
controller
if
controller_set
@scope
[
:options
]
=
options
@scope
[
:blocks
]
=
blocks
@scope
[
:constraints
]
=
constraints
end
...
...
@@ -311,12 +356,12 @@ def resource(*resources, &block)
with_scope_level
(
:resource
,
resource
)
do
yield
if
block_given?
get
"(.:format)"
,
:to
=>
:show
,
:as
=>
resource
.
member_name
post
"(.:format)"
,
:to
=>
:create
put
"(.:format)"
,
:to
=>
:update
delete
"(.:format)"
,
:to
=>
:destroy
get
"/new(.:format)"
,
:to
=>
:new
,
:as
=>
"new_
#{
resource
.
singular
}
"
get
"/edit(.:format)"
,
:to
=>
:edit
,
:as
=>
"edit_
#{
resource
.
singular
}
"
get
"(.:format)"
,
:to
=>
:show
,
:as
=>
resource
.
member_name
post
"(.:format)"
,
:to
=>
:create
put
"(.:format)"
,
:to
=>
:update
delete
"(.:format)"
,
:to
=>
:destroy
get
"/new(.:format)"
,
:to
=>
:new
,
:as
=>
"new_
#{
resource
.
singular
}
"
get
"/edit(.:format)"
,
:to
=>
:edit
,
:as
=>
"edit_
#{
resource
.
singular
}
"
end
end
...
...
@@ -346,8 +391,9 @@ def resources(*resources, &block)
yield
if
block_given?
with_scope_level
(
:collection
)
do
get
"(.:format)"
,
:to
=>
:index
,
:as
=>
resource
.
collection_name
get
"(.:format)"
,
:to
=>
:index
,
:as
=>
resource
.
collection_name
post
"(.:format)"
,
:to
=>
:create
with_exclusive_name_prefix
:new
do
get
"/new(.:format)"
,
:to
=>
:new
,
:as
=>
resource
.
singular
end
...
...
@@ -355,9 +401,10 @@ def resources(*resources, &block)
with_scope_level
(
:member
)
do
scope
(
"/:id"
)
do
get
"(.:format)"
,
:to
=>
:show
,
:as
=>
resource
.
member_name
put
"(.:format)"
,
:to
=>
:update
get
"(.:format)"
,
:to
=>
:show
,
:as
=>
resource
.
member_name
put
"(.:format)"
,
:to
=>
:update
delete
"(.:format)"
,
:to
=>
:destroy
with_exclusive_name_prefix
:edit
do
get
"/edit(.:format)"
,
:to
=>
:edit
,
:as
=>
resource
.
singular
end
...
...
@@ -473,4 +520,4 @@ def with_scope_level(kind, resource = parent_resource)
include
Resources
end
end
end
end
\ No newline at end of file
actionpack/test/dispatch/routing_test.rb
浏览文件 @
2b7256a4
...
...
@@ -22,7 +22,7 @@ def self.matches?(request)
delete
'logout'
,
:to
=>
:destroy
,
:as
=>
:logout
end
match
'account/logout'
=>
redirect
(
"/logout"
)
match
'account/logout'
=>
redirect
(
"/logout"
)
,
:as
=>
:logout_redirect
match
'account/login'
,
:to
=>
redirect
(
"/login"
)
match
'account/modulo/:name'
,
:to
=>
redirect
(
"/%{name}s"
)
...
...
@@ -110,6 +110,7 @@ def self.matches?(request)
resources
:rooms
end
match
'/info'
=>
'projects#info'
,
:as
=>
'info'
root
:to
=>
'projects#index'
end
end
...
...
@@ -153,6 +154,7 @@ def test_login_redirect
def
test_logout_redirect_without_to
with_test_routes
do
assert_equal
'/account/logout'
,
logout_redirect_path
get
'/account/logout'
assert_equal
301
,
@response
.
status
assert_equal
'http://www.example.com/logout'
,
@response
.
headers
[
'Location'
]
...
...
@@ -462,10 +464,19 @@ def test_access_token_rooms
def
test_root
with_test_routes
do
assert_equal
'/'
,
root_path
get
'/'
assert_equal
'projects#index'
,
@response
.
body
end
end
def
test_index
with_test_routes
do
assert_equal
'/info'
,
info_path
get
'/info'
assert_equal
'projects#info'
,
@response
.
body
end
end
private
def
with_test_routes
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录