Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
f59984cc
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,体验更适合开发者的 AI 搜索 >>
提交
f59984cc
编写于
8月 01, 2009
作者:
J
José Valim
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add nagivational behavior to respond_with.
上级
c44f7e39
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
215 addition
and
78 deletion
+215
-78
actionpack/lib/action_controller/metal/conditional_get.rb
actionpack/lib/action_controller/metal/conditional_get.rb
+4
-3
actionpack/lib/action_controller/metal/mime_responds.rb
actionpack/lib/action_controller/metal/mime_responds.rb
+110
-47
actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
...ction_controller/routing/generation/polymorphic_routes.rb
+10
-11
actionpack/test/controller/mime_responds_test.rb
actionpack/test/controller/mime_responds_test.rb
+73
-16
actionpack/test/controller/render_test.rb
actionpack/test/controller/render_test.rb
+15
-0
actionpack/test/fixtures/respond_with/edit.html.erb
actionpack/test/fixtures/respond_with/edit.html.erb
+1
-0
actionpack/test/fixtures/respond_with/new.html.erb
actionpack/test/fixtures/respond_with/new.html.erb
+1
-0
actionpack/test/fixtures/respond_with/using_resource.html.erb
...onpack/test/fixtures/respond_with/using_resource.html.erb
+0
-1
actionpack/test/fixtures/respond_with/using_resource.js.rjs
actionpack/test/fixtures/respond_with/using_resource.js.rjs
+1
-0
未找到文件。
actionpack/lib/action_controller/metal/conditional_get.rb
浏览文件 @
f59984cc
...
...
@@ -55,14 +55,15 @@ def head(*args)
elsif
args
.
empty?
raise
ArgumentError
,
"too few arguments to head"
end
options
=
args
.
extract_options!
status
=
args
.
shift
||
options
.
delete
(
:status
)
||
:ok
options
=
args
.
extract_options!
status
=
args
.
shift
||
options
.
delete
(
:status
)
||
:ok
location
=
options
.
delete
(
:location
)
options
.
each
do
|
key
,
value
|
headers
[
key
.
to_s
.
dasherize
.
split
(
/-/
).
map
{
|
v
|
v
.
capitalize
}.
join
(
"-"
)]
=
value
.
to_s
end
render
:nothing
=>
true
,
:status
=>
status
render
:nothing
=>
true
,
:status
=>
status
,
:location
=>
location
end
# Sets the etag and/or last_modified on the response and checks it against
...
...
actionpack/lib/action_controller/metal/mime_responds.rb
浏览文件 @
f59984cc
...
...
@@ -198,11 +198,11 @@ def respond_to(*mimes, &block)
end
# respond_with allows you to respond an action with a given resource. It
# requires that you set your class with a
:
respond_to method with the
# requires that you set your class with a respond_to method with the
# formats allowed:
#
# class PeopleController < ApplicationController
# respond_to :xml, :json
# respond_to :
html, :
xml, :json
#
# def index
# @people = Person.find(:all)
...
...
@@ -210,14 +210,43 @@ def respond_to(*mimes, &block)
# end
# end
#
# When a request comes with format :xml, the respond_with will first search
# for a template as person/index.xml, if the template is not available, it
# will see if the given resource responds to :to_xml.
# When a request comes, for example with format :xml, three steps happen:
#
# 1) respond_with searches for a template at people/index.xml;
#
# 2) if the template is not available, it will check if the given
# resource responds to :to_xml.
#
# 3) if a :location option was provided, redirect to the location with
# redirect status if a string was given, or render an action if a
# symbol was given.
#
# If all steps fail, a missing template error will be raised.
#
# === Supported options
#
# [status]
# Sets the response status.
#
# [head]
# Tell respond_with to set the content type, status and location header,
# but do not render the object, leaving the response body empty. This
# option only has effect if the resource is being rendered. If a
# template was found, it's going to be rendered anyway.
#
# [location]
# Sets the location header with the given value. It accepts a string,
# representing the location header value, or a symbol representing an
# action name.
#
# === Builtin HTTP verb semantics
#
# If neither are available, it will raise an error.
# respond_with holds semantics for each HTTP verb. Depending on the verb
# and the resource status, respond_with will automatically set the options
# above.
#
#
respond_with holds semantics for each HTTP verb. The example above cover
#
GET requests. Let's check a POST request example
:
#
Above we saw an example for GET requests, where actually no option is
#
configured. A create action for POST requests, could be written as
:
#
# def create
# @person = Person.new(params[:person])
...
...
@@ -225,34 +254,40 @@ def respond_to(*mimes, &block)
# respond_with(@person)
# end
#
#
Since the request is a POST, respond_with will check wether @people
#
resource have errors or not. If it has errors, it will render the error
#
object with unprocessable entity status (422).
#
respond_with will inspect the @person object and check if we have any
#
error. If errors are empty, it will add status and location to the options
#
hash. Then the create action in case of success, is equivalent to this:
#
# If no error was found, it will render the @people resource, with status
# created (201) and location header set to person_url(@people).
# respond_with(@person, :status => :created, :location => @person)
#
# If you also want to provide html behavior in the method above, you can
# supply a block to customize it:
# From them on, the lookup happens as described above. Let's suppose a :xml
# request and we don't have a people/create.xml template. But since the
# @person object responds to :to_xml, it will render the newly created
# resource and set status and location.
#
# class PeopleController < ApplicationController
# respond_to :html, :xml, :json # Add :html to respond_to definition
#
# def create
# @person = Person.new(params[:pe])
#
# respond_with(@person) do |format|
# if @person.save
# flash[:notice] = 'Person was successfully created.'
# format.html { redirect_to @person }
# else
# format.html { render :action => "new" }
# end
# end
# However, if the request is :html, a template is not available and @person
# does not respond to :to_html. But since a :location options was provided,
# it will redirect to it.
#
# In case of failures (when the @person could not be saved and errors are
# not empty), respond_with can be expanded as this:
#
# respond_with(@person.errors, :status => :unprocessable_entity, :location => :new)
#
# In other words, respond_with(@person) for POST requests is expanded
# internally into this:
#
# def create
# @person = Person.new(params[:person])
#
# if @person.save
# respond_with(@person, :status => :created, :location => @person)
# else
# respond_with(@person.errors, :status => :unprocessable_entity, :location => :new)
# end
# end
#
#
It works similarly for PUT requests
:
#
For an update action for PUT requests, we would have
:
#
# def update
# @person = Person.find(params[:id])
...
...
@@ -260,10 +295,23 @@ def respond_to(*mimes, &block)
# respond_with(@person)
# end
#
# In case of failures, it works as POST requests, but in success failures
# it just reply status ok (200) to the client.
# Which, in face of success and failure scenarios, can be expanded as:
#
# A DELETE request also works in the same way:
# def update
# @person = Person.find(params[:id])
# @person.update_attributes(params[:person])
#
# if @person.save
# respond_with(@person, :status => :ok, :location => @person, :head => true)
# else
# respond_with(@person.errors, :status => :unprocessable_entity, :location => :edit)
# end
# end
#
# Notice that in case of success, we just need to reply :ok to the client.
# The option :head ensures that the object is not rendered.
#
# Finally, we have the destroy action with DELETE verb:
#
# def destroy
# @person = Person.find(params[:id])
...
...
@@ -271,21 +319,30 @@ def respond_to(*mimes, &block)
# respond_with(@person)
# end
#
# It just replies with status ok, indicating the record was successfuly
# destroyed.
# Which is expanded as:
#
# def destroy
# @person = Person.find(params[:id])
# @person.destroy
# respond_with(@person, :status => :ok, :location => @person, :head => true)
# end
#
# In this case, since @person.destroyed? returns true, polymorphic urls will
# redirect to the collection url, instead of the resource url.
#
def
respond_with
(
resource
,
options
=
{},
&
block
)
respond_to
(
&
block
)
rescue
ActionView
::
MissingTemplate
=>
e
format
=
self
.
formats
.
first
resource
=
normalize_resource_options_by_verb
(
resource
,
options
)
action
=
options
.
delete
(
:location
)
if
options
[
:location
].
is_a?
(
Symbol
)
if
resource
.
respond_to?
(
:"to_
#{
format
}
"
)
if
options
.
delete
(
:no_content
)
head
options
else
render
options
.
merge
(
format
=>
resource
)
end
options
.
delete
(
:head
)
?
head
(
options
)
:
render
(
options
.
merge
(
format
=>
resource
)
)
elsif
action
render
:action
=>
action
elsif
options
[
:location
]
redirect_to
options
[
:location
]
else
raise
e
end
...
...
@@ -296,16 +353,22 @@ def respond_with(resource, options={}, &block)
# Change respond with behavior based on the HTTP verb.
#
def
normalize_resource_options_by_verb
(
resource_or_array
,
options
)
resource
=
resource_or_array
.
is_a?
(
Array
)
?
resource_or_array
.
last
:
resource_or_array
has_errors
=
resource
.
respond_to?
(
:errors
)
&&
!
resource
.
errors
.
empty?
resource
=
resource_or_array
.
is_a?
(
Array
)
?
resource_or_array
.
last
:
resource_or_array
if
has_errors
&&
(
request
.
post?
||
request
.
put?
)
options
.
reverse_merge!
(
:status
=>
:unprocessable_entity
)
if
resource
.
respond_to?
(
:errors
)
&&
!
resource
.
errors
.
empty?
options
[
:status
]
||=
:unprocessable_entity
options
[
:location
]
||=
:new
if
request
.
post?
options
[
:location
]
||=
:edit
if
request
.
put?
return
resource
.
errors
elsif
request
.
post?
options
.
reverse_merge!
(
:status
=>
:created
,
:location
=>
resource_or_array
)
elsif
!
request
.
get?
options
.
reverse_merge!
(
:status
=>
:ok
,
:no_content
=>
true
)
options
[
:location
]
||=
resource_or_array
if
request
.
post?
options
[
:status
]
||=
:created
else
options
[
:status
]
||=
:ok
options
[
:head
]
=
true
unless
options
.
key?
(
:head
)
end
end
return
resource
...
...
actionpack/lib/action_controller/routing/generation/polymorphic_routes.rb
浏览文件 @
f59984cc
...
...
@@ -86,17 +86,16 @@ def polymorphic_url(record_or_hash_or_array, options = {})
else
[
record_or_hash_or_array
]
end
inflection
=
case
when
options
[
:action
].
to_s
==
"new"
args
.
pop
:singular
when
record
.
respond_to?
(
:new_record?
)
&&
record
.
new_record?
args
.
pop
:plural
else
:singular
end
inflection
=
if
options
[
:action
].
to_s
==
"new"
args
.
pop
:singular
elsif
(
record
.
respond_to?
(
:new_record?
)
&&
record
.
new_record?
)
||
(
record
.
respond_to?
(
:destroyed?
)
&&
record
.
destroyed?
)
args
.
pop
:plural
else
:singular
end
args
.
delete_if
{
|
arg
|
arg
.
is_a?
(
Symbol
)
||
arg
.
is_a?
(
String
)}
...
...
actionpack/test/controller/mime_responds_test.rb
浏览文件 @
f59984cc
...
...
@@ -493,6 +493,10 @@ def to_js
def
errors
[]
end
def
destroyed?
false
end
end
class
ParentResource
...
...
@@ -508,7 +512,7 @@ def to_param
class
RespondWithController
<
ActionController
::
Base
respond_to
:html
,
:json
respond_to
:xml
,
:except
=>
:using_defaults
respond_to
:js
,
:only
=>
:using_defaults
respond_to
:js
,
:only
=>
[
:using_defaults
,
:using_resource
]
def
using_defaults
respond_to
do
|
format
|
...
...
@@ -547,12 +551,16 @@ def _render_js(js, options)
self
.
response_body
=
js
.
respond_to?
(
:to_js
)
?
js
.
to_js
:
js
end
def
resources_url
request
.
host
+
"/resources"
end
def
resource_url
(
resource
)
request
.
host
+
"/resource/
#{
resource
.
to_param
}
"
request
.
host
+
"/resource
s
/
#{
resource
.
to_param
}
"
end
def
parent_resource_url
(
parent
,
resource
)
request
.
host
+
"/parent
/
#{
parent
.
to_param
}
/resource
/
#{
resource
.
to_param
}
"
request
.
host
+
"/parent
s/
#{
parent
.
to_param
}
/resources
/
#{
resource
.
to_param
}
"
end
end
...
...
@@ -617,10 +625,10 @@ def test_default_overwritten
end
def
test_using_resource
@request
.
accept
=
"text/
html
"
@request
.
accept
=
"text/
javascript
"
get
:using_resource
assert_equal
"text/
html
"
,
@response
.
content_type
assert_equal
"Hello world!"
,
@response
.
body
assert_equal
"text/
javascript
"
,
@response
.
content_type
assert_equal
'$("body").visualEffect("highlight");'
,
@response
.
body
@request
.
accept
=
"application/xml"
get
:using_resource
...
...
@@ -633,14 +641,30 @@ def test_using_resource
end
end
def
test_using_resource_for_post
def
test_using_resource_for_post_with_html
post
:using_resource
assert_equal
"text/html"
,
@response
.
content_type
assert_equal
302
,
@response
.
status
assert_equal
"www.example.com/resources/13"
,
@response
.
location
assert
@response
.
redirect?
errors
=
{
:name
=>
:invalid
}
RespondResource
.
any_instance
.
stubs
(
:errors
).
returns
(
errors
)
post
:using_resource
assert_equal
"text/html"
,
@response
.
content_type
assert_equal
200
,
@response
.
status
assert_equal
"New world!
\n
"
,
@response
.
body
assert_nil
@response
.
location
end
def
test_using_resource_for_post_with_xml
@request
.
accept
=
"application/xml"
post
:using_resource
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
201
,
@response
.
status
assert_equal
"XML"
,
@response
.
body
assert_equal
"www.example.com/resource/13"
,
@response
.
location
assert_equal
"www.example.com/resource
s
/13"
,
@response
.
location
errors
=
{
:name
=>
:invalid
}
RespondResource
.
any_instance
.
stubs
(
:errors
).
returns
(
errors
)
...
...
@@ -651,14 +675,30 @@ def test_using_resource_for_post
assert_nil
@response
.
location
end
def
test_using_resource_for_put
def
test_using_resource_for_put_with_html
put
:using_resource
assert_equal
"text/html"
,
@response
.
content_type
assert_equal
302
,
@response
.
status
assert_equal
"www.example.com/resources/13"
,
@response
.
location
assert
@response
.
redirect?
errors
=
{
:name
=>
:invalid
}
RespondResource
.
any_instance
.
stubs
(
:errors
).
returns
(
errors
)
put
:using_resource
assert_equal
"text/html"
,
@response
.
content_type
assert_equal
200
,
@response
.
status
assert_equal
"Edit world!
\n
"
,
@response
.
body
assert_nil
@response
.
location
end
def
test_using_resource_for_put_with_xml
@request
.
accept
=
"application/xml"
put
:using_resource
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
200
,
@response
.
status
assert_equal
" "
,
@response
.
body
assert_
nil
@response
.
location
assert_
equal
"www.example.com/resources/13"
,
@response
.
location
errors
=
{
:name
=>
:invalid
}
RespondResource
.
any_instance
.
stubs
(
:errors
).
returns
(
errors
)
...
...
@@ -666,16 +706,25 @@ def test_using_resource_for_put
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
422
,
@response
.
status
assert_equal
errors
.
to_xml
,
@response
.
body
assert_nil
@response
.
location
assert_nil
@response
.
location
end
def
test_using_resource_for_delete
def
test_using_resource_for_delete_with_html
RespondResource
.
any_instance
.
stubs
(
:destroyed?
).
returns
(
true
)
delete
:using_resource
assert_equal
"text/html"
,
@response
.
content_type
assert_equal
302
,
@response
.
status
assert_equal
"www.example.com/resources"
,
@response
.
location
end
def
test_using_resource_for_delete_with_xml
RespondResource
.
any_instance
.
stubs
(
:destroyed?
).
returns
(
true
)
@request
.
accept
=
"application/xml"
delete
:using_resource
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
200
,
@response
.
status
assert_equal
" "
,
@response
.
body
assert_
nil
@response
.
location
assert_
equal
"www.example.com/resources"
,
@response
.
location
end
def
test_using_resource_with_options
...
...
@@ -692,14 +741,22 @@ def test_using_resource_with_options
assert_equal
"JS"
,
@response
.
body
end
def
test_using_resource_with_parent
def
test_using_resource_with_parent_for_get
@request
.
accept
=
"application/xml"
get
:using_resource_with_parent
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
200
,
@response
.
status
assert_equal
"XML"
,
@response
.
body
end
def
test_using_resource_with_parent_for_post
@request
.
accept
=
"application/xml"
post
:using_resource_with_parent
assert_equal
"application/xml"
,
@response
.
content_type
assert_equal
201
,
@response
.
status
assert_equal
"XML"
,
@response
.
body
assert_equal
"www.example.com/parent
/11/resource
/13"
,
@response
.
location
assert_equal
"www.example.com/parent
s/11/resources
/13"
,
@response
.
location
errors
=
{
:name
=>
:invalid
}
RespondResource
.
any_instance
.
stubs
(
:errors
).
returns
(
errors
)
...
...
@@ -739,7 +796,7 @@ def test_not_acceptable
assert_equal
406
,
@response
.
status
@request
.
accept
=
"text/javascript"
get
:
using_resource
get
:
default_overwritten
assert_equal
406
,
@response
.
status
end
end
...
...
actionpack/test/controller/render_test.rb
浏览文件 @
f59984cc
...
...
@@ -458,6 +458,10 @@ def head_with_location_header
head
:location
=>
"/foo"
end
def
head_with_location_object
head
:location
=>
Customer
.
new
(
"david"
)
end
def
head_with_symbolic_status
head
:status
=>
params
[
:status
].
intern
end
...
...
@@ -618,6 +622,10 @@ def rescue_action(e)
end
private
def
customer_url
(
customer
)
request
.
host
+
"/customers/1"
end
def
determine_layout
case
action_name
when
"hello_world"
,
"layout_test"
,
"rendering_without_layout"
,
...
...
@@ -1084,6 +1092,13 @@ def test_head_with_location_header
assert_response
:ok
end
def
test_head_with_location_object
get
:head_with_location_object
assert
@response
.
body
.
blank?
assert_equal
"www.nextangle.com/customers/1"
,
@response
.
headers
[
"Location"
]
assert_response
:ok
end
def
test_head_with_custom_header
get
:head_with_custom_header
assert
@response
.
body
.
blank?
...
...
actionpack/test/fixtures/respond_with/edit.html.erb
0 → 100644
浏览文件 @
f59984cc
Edit world!
actionpack/test/fixtures/respond_with/new.html.erb
0 → 100644
浏览文件 @
f59984cc
New world!
actionpack/test/fixtures/respond_with/using_resource.html.erb
已删除
100644 → 0
浏览文件 @
c44f7e39
Hello world!
\ No newline at end of file
actionpack/test/fixtures/respond_with/using_resource.js.rjs
0 → 100644
浏览文件 @
f59984cc
page[:body].visual_effect :highlight
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录