We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从控制器的角度,创建HTTP响应有三种方法:
调用 render 方法
render
调用 redirect_to 方法
redirect_to
调用 head 方法,向浏览器发送只含HTTP首部的响应
head
一个控制器:
class BooksController < ApplicationController def index @books = Book.all end end
基于“多约定,少配置”原则,在 index 动作末尾并没有指定要渲染的视图,Rails会自动在控制器的视图文件夹中寻找 action_name.html.erb 模板,然后渲染。这里渲染的就是 app/views/books/index.html.erb
index
action_name.html.erb
app/views/books/index.html.erb
render 方法的行为有多种定制方式,可以渲染Rails模板的默认视图、指定的模板、文件、行间代码或者什么也不渲染。渲染的内容可以是 文本 、JSON 或者 XML,而且可以设置响应的内容类型和HTTP状态码。
渲染同个控制器的其他模板
def update @book = Book.find(params[:id]) if @book.update(book_params) redirect_to @book else render "edit" end end
不想用字符串,也可以使用符号:
render :edit
渲染其他控制器的动作 使用 render 方法,指定模板的完整路径(相对于 app/views)即可。
app/views
render "products/show"
为了代码意图更加明显,还可以使用 :template 选项:
:template
render template: "products/show"
渲染任意文件
render file: "/u/apps/warehouse_app/current/app/views/products/show"
想要渲染 views/books 下的 edit.html.erb 模板,以下方法都行:
views/books
render :edit render action: :edit render "edit" render "edit.html.erb" render action: "edit" render action: "edit.html.erb" render "books/edit" render "books/edit.html.erb" render template: "books/edit" render template: "books/edit.html.erb" render "/path/to/rails/app/views/books/edit" render "/path/to/rails/app/views/books/edit.html.erb" render file: "/path/to/rails/app/views/books/edit" render file: "/path/to/rails/app/views/books/edit.html.erb"
渲染纯文本 使用 :plain 选项,可以把没有标记语言的纯文本发给浏览器,这主要用于响应Ajax或无需使用HTML的网络服务。
:plain
render plain: "OK"
渲染HTML 使用 :html 选项可以把HTML字符串发送给浏览器:
:html
render html: "<p>hello, world</p>".html_safe
如果没调用 html_safe 方法,HTML实体会转义
html_safe
渲染JSON
render json: @product
在需要渲染的对象上无需调用 to_json 方法,使用了 :json 选项,render 方法会自动调用 to_json 。
to_json
:json
渲染XML
render xml: @product
在需要渲染的对象上无需调用 to_xml 方法,使用了 :xml 选项,render 方法会自动调用 to_xml 。
to_xml
:xml
渲染javascript
render js: "alert('hello, rails')"
此时发送给浏览器的字符串,其MIME类型就是 text/javascript
text/javascript
渲染原始的主体
render body: "raw"
这时候返回的类型是 text/html ,只有在不在意内容类型的时候才应该使用这个选项。大多数时候,使用 :plain 或 :html 选项更加合适。
text/html
render 方法一般还可接受其他5个选项:
:content_type
:layout
:location
:status
:formats
:content_type选项 默认情况下,Rails渲染得到的结果内容类型为 text/html,如果使用 :json 选项,内容类型为 application/json,如果使用 :xml 选项,则内容类型为 application/xml ,如果需要修改内容类型,可使用 :content_type 选项:
application/json
application/xml
render file: filename, content_type: "application/rss"
:layout 选项 render 方法大部分渲染得到的结果都会作为当前布局的一部分显示,:layout 选项指定使用特定的文件作为布局:
render layout: "special_layout"
当设置为 false 时,则说明不使用布局:
false
render layout: false
:location选项 用于设置HTTP的location首部:
render xml: photo, location: photo_url(photo)
:status选项 设定HTTP状态码,(在大多数情况下都是200),可以使用HTTP状态码,也可以使用状态码含义设定。
render status: 500 render status: :forbidden
:formats选项 改变格式,值可以是一个符号或者一个数组,默认使用 :html:
render formats: :xml render formats: [:json, :xml]
查找布局时,首先在文件夹 app/views/layouts 文件夹中是否有和控制器同名的文件。例如,渲染 PhotosController 中的动作会使用 app/views/layouts/photo.html.erb 或者 app/views/layouts/photos.builder 。如果没有针对控制器的布局,Rails会使用 app/views/layouts/application.html.erb 或 app/views/layouts/application.builder 。如果没有 .erb 布局,Rails会使用 .builder 布局。
app/views/layouts
PhotosController
app/views/layouts/photo.html.erb
app/views/layouts/photos.builder
app/views/layouts/application.html.erb
app/views/layouts/application.builder
.erb
.builder
指定控制器的布局 在控制器中使用 layout 声明,可以覆盖默认使用的布局约定:
class ProductsController < ApplicationController layout "inventory" end
若要指定整个应用使用的布局,可以在ApplicationController类中使用layout声明:
class ApplicationController < ActionController::Base layout "main" end
在运行时选择布局 使用符号把布局延后到处理请求时再选择:
class ProductsController < ApplicationController layout :products_layout def show @product = Product.find(params[:id]) end private def products_layout @current_user.special? ? "special" : "products" end
现在,如果用户是特殊用户,会使用一个特殊的布局渲染。
根据条件设定布局 使用 :only 和 :except 选项,可以设定条件
:only
:except
class ProductsController < ApplicationController layout "product", except: [:index, :rss] end
redirect_to 方法告诉浏览器向另一个URL发起新请求:
redirect_to photos_url
可以使用 redirect_back 把用户带回他们之前所在的页面,页面地址从 http_referer 中获取,不过浏览器不一定会设定,所以需要设定 fallback_location
redirect_back
http_referer
fallback_location
redirect_back(fallback_location: root_path)
默认 redirect_to 方法把HTTP状态码设为302,如果想要设定其他状态码,可以使用 :status 选项:
redirect_to photos_path, status: 301
head 方法只把首部发送给浏览器,参数是HTTP状态码数字,或者符号形式,选项是一个散列,指定首部的名称和对应的值
head :bad_request head :created, location: photo_path(@photo)
aotu_discovery_link_tag
javascript_include_tag
stylesheet_link_tag
image_tag
video_tag
audio_tag
<%= auto_discovery_link_tag(:rss, {action: "feed"}, {title: "RSS Feed"}) %>
Rails应用的javascript文件可以存放在三个位置: app/assets 、lib/assets 、vendor/assets。文件的地址可使用相对文档根目录的完整路径或URL。例如,如果想链接到 app/assets、lib/assets 或 vendor/assets 文件夹中名为 javascripts 的子文件夹中的文件,可以这么做:
app/assets
lib/assets
vendor/assets
<%= javascript_include_tag "main" %>
Rails生成的script标签如下:
<script src="/assets/main.js"></script>
同时引入多个文件:
<%= javascript_include_tag "main", "columns" %>
引入外部文件:
<%= javascript_include_tag "http://example.com/main.js" %>
类似于 javascript_include_tag
<%= stylesheet_link_tag "main" %>
<%= stylesheet_link_tag "main", "column" %>
默认情况下, stylesheet_link_tag 创建的链接属性为 media="screen" rel="stylesheet",指定相应的选项可以覆盖默认值:
<%= stylesheet_link_tag "main_print", media: "print" %>
生成img标签,默认从 public/images 文件夹中加载文件:
public/images
<%= image_tag "header.png" %>
文件名必须指定图像的拓展名
同样可以通过散列指定HTML属性,另外如果没有 alt 属性, Rails会使用图片的首字母大写的文件名(去掉拓展名)。
alt
<%= image_tag "home.gif" %> <%= image_tag "home.gif", alt: "Home" %>
生成 <video> 标签,默认从 public/vedios 文件夹中加载文件。
<video>
public/vedios
<%= video_tag "movie.ogg" %>
生成
<video src="/videos/movie.ogg" />
同样也支持散列指定HTML属性。 把数组传递给 video_tag 方法可以指定多个视频
<%= video ["trailer.ogg", "movie.ogg"] %>
<video> <source src="trailer.ogg" /> <source src="movie.ogg" /> </video>
生成 <audio> 标签,默认从 public/audio 文件夹中加载
<audio>
public/audio
<%= audio_tag "music.mp3" %>
在布局中,yield 标明一个区域,渲染的视图会插在这里,最简单的情况是只有一个 yield ,此时渲染的整个视图都会插入在这个区域:
yield
<html> <head></head> <body> <%= yield %> </body> </html>
表明多个区域:
<html> <head> <%= yield %> </head> <body> <%= yield %> </body> </html>
视图的主体会插入未命名的yield区域,若想在具名yield中插入内容,可以使用 content_for 方法。
content_for
<% content_for :head do %> <title>A simple page</title> <% end %> <p>Hello, World!</p>
套入布局后生成:
<html> <head> <title>A simple page</title> </head> <body> <p>Hello, World!</p> </body> </html>
如果不同区域需要不同的内容(sidebar、footer等),就可以使用 content_for 方法。
<%= render "menu" %>
这会渲染名为 _menu.html.erb 的文件,局部视图的文件名都是以下划线开头的,以便和普通视图区分开,引用时无需加入下划线。
_menu.html.erb
局部布局 与视图使用布局一样,局部视图也可以使用布局
<%= render partial: "link_area", layout: "graybar" %>
这里会使用 _graybar.html.erb 布局渲染局部视图 _link_area.html.erb ,此时局部布局与局部视图保存在同一个文件夹中。
_graybar.html.erb
_link_area.html.erb
传递局部变量 局部变量可以传入局部视图,这样可以使得局部视图更加强大、更加灵活。
new.html.erb
<h1>New zone</h1> <%= render partial: "form", locals: {zone: @zone} %>
edit.html.erb
<h1>Editing zone</h1> <%= render partial: "form", locals: {zone: @zone} %>
_form.html.erb
<%= form_for(zone) do |f| %> <p> <b>Zone name</b><br> <%= f.text_field :name %> </p> <p> <%= f.submit %> </p> <% end %>
每个局部视图中都有一个和局部视图同名的局部变量,通过object选项可以把这个对象传给这个变量:
<%= render partial: "customer", object: @new_customer %>
如果要在局部视图中渲染模型实例,可以使用简写:
<%= render @customer %>
如果要在局部视图中自定义局部变量的名字,可以使用 :as 选项指定:
:as
<%= render partial: "product", collection: @products, as: :item %>
The text was updated successfully, but these errors were encountered:
No branches or pull requests
创建响应
从控制器的角度,创建HTTP响应有三种方法:
调用
render
方法调用
redirect_to
方法调用
head
方法,向浏览器发送只含HTTP首部的响应一个控制器:
基于“多约定,少配置”原则,在
index
动作末尾并没有指定要渲染的视图,Rails会自动在控制器的视图文件夹中寻找action_name.html.erb
模板,然后渲染。这里渲染的就是app/views/books/index.html.erb
使用render方法
render
方法的行为有多种定制方式,可以渲染Rails模板的默认视图、指定的模板、文件、行间代码或者什么也不渲染。渲染的内容可以是 文本 、JSON 或者 XML,而且可以设置响应的内容类型和HTTP状态码。渲染同个控制器的其他模板
不想用字符串,也可以使用符号:
渲染其他控制器的动作
使用
render
方法,指定模板的完整路径(相对于app/views
)即可。为了代码意图更加明显,还可以使用
:template
选项:渲染任意文件
想要渲染
views/books
下的 edit.html.erb 模板,以下方法都行:渲染纯文本
使用
:plain
选项,可以把没有标记语言的纯文本发给浏览器,这主要用于响应Ajax或无需使用HTML的网络服务。渲染HTML
使用
:html
选项可以把HTML字符串发送给浏览器:如果没调用
html_safe
方法,HTML实体会转义渲染JSON
在需要渲染的对象上无需调用
to_json
方法,使用了:json
选项,render
方法会自动调用to_json
。渲染XML
在需要渲染的对象上无需调用
to_xml
方法,使用了:xml
选项,render
方法会自动调用to_xml
。渲染javascript
此时发送给浏览器的字符串,其MIME类型就是
text/javascript
渲染原始的主体
这时候返回的类型是
text/html
,只有在不在意内容类型的时候才应该使用这个选项。大多数时候,使用:plain
或:html
选项更加合适。render 方法的其它选项
render
方法一般还可接受其他5个选项::content_type
:layout
:location
:status
:formats
:content_type选项
默认情况下,Rails渲染得到的结果内容类型为
text/html
,如果使用:json
选项,内容类型为application/json
,如果使用:xml
选项,则内容类型为application/xml
,如果需要修改内容类型,可使用:content_type
选项::layout 选项
render
方法大部分渲染得到的结果都会作为当前布局的一部分显示,:layout
选项指定使用特定的文件作为布局:当设置为
false
时,则说明不使用布局::location选项
用于设置HTTP的location首部:
:status选项
设定HTTP状态码,(在大多数情况下都是200),可以使用HTTP状态码,也可以使用状态码含义设定。
:formats选项
改变格式,值可以是一个符号或者一个数组,默认使用
:html
:查找布局
查找布局时,首先在文件夹
app/views/layouts
文件夹中是否有和控制器同名的文件。例如,渲染PhotosController
中的动作会使用app/views/layouts/photo.html.erb
或者app/views/layouts/photos.builder
。如果没有针对控制器的布局,Rails会使用app/views/layouts/application.html.erb
或app/views/layouts/application.builder
。如果没有.erb
布局,Rails会使用.builder
布局。指定控制器的布局
在控制器中使用 layout 声明,可以覆盖默认使用的布局约定:
若要指定整个应用使用的布局,可以在ApplicationController类中使用layout声明:
在运行时选择布局
使用符号把布局延后到处理请求时再选择:
现在,如果用户是特殊用户,会使用一个特殊的布局渲染。
根据条件设定布局
使用
:only
和:except
选项,可以设定条件使用 redirect_to 方法
redirect_to
方法告诉浏览器向另一个URL发起新请求:可以使用
redirect_back
把用户带回他们之前所在的页面,页面地址从http_referer
中获取,不过浏览器不一定会设定,所以需要设定fallback_location
默认
redirect_to
方法把HTTP状态码设为302,如果想要设定其他状态码,可以使用:status
选项:使用head方法
head
方法只把首部发送给浏览器,参数是HTTP状态码数字,或者符号形式,选项是一个散列,指定首部的名称和对应的值布局的结构
静态资源标签辅助方法
aotu_discovery_link_tag
javascript_include_tag
stylesheet_link_tag
image_tag
video_tag
audio_tag
aotu_discovery_link_tag 链接到订阅源
javascript_include_tag
Rails应用的javascript文件可以存放在三个位置:
app/assets
、lib/assets
、vendor/assets
。文件的地址可使用相对文档根目录的完整路径或URL。例如,如果想链接到 app/assets、lib/assets 或 vendor/assets 文件夹中名为 javascripts 的子文件夹中的文件,可以这么做:Rails生成的script标签如下:
同时引入多个文件:
引入外部文件:
stylesheet_link_tag
类似于
javascript_include_tag
默认情况下,
stylesheet_link_tag
创建的链接属性为 media="screen" rel="stylesheet",指定相应的选项可以覆盖默认值:image_tag
生成img标签,默认从
public/images
文件夹中加载文件:文件名必须指定图像的拓展名
同样可以通过散列指定HTML属性,另外如果没有
alt
属性,Rails会使用图片的首字母大写的文件名(去掉拓展名)。
video_tag
生成
<video>
标签,默认从public/vedios
文件夹中加载文件。生成
同样也支持散列指定HTML属性。
把数组传递给
video_tag
方法可以指定多个视频生成
audio_tag
生成
<audio>
标签,默认从public/audio
文件夹中加载yield
在布局中,
yield
标明一个区域,渲染的视图会插在这里,最简单的情况是只有一个yield
,此时渲染的整个视图都会插入在这个区域:表明多个区域:
视图的主体会插入未命名的yield区域,若想在具名yield中插入内容,可以使用
content_for
方法。套入布局后生成:
如果不同区域需要不同的内容(sidebar、footer等),就可以使用
content_for
方法。使用局部视图
这会渲染名为
_menu.html.erb
的文件,局部视图的文件名都是以下划线开头的,以便和普通视图区分开,引用时无需加入下划线。局部布局
与视图使用布局一样,局部视图也可以使用布局
这里会使用
_graybar.html.erb
布局渲染局部视图_link_area.html.erb
,此时局部布局与局部视图保存在同一个文件夹中。传递局部变量
局部变量可以传入局部视图,这样可以使得局部视图更加强大、更加灵活。
new.html.erb
edit.html.erb
_form.html.erb
每个局部视图中都有一个和局部视图同名的局部变量,通过object选项可以把这个对象传给这个变量:
如果要在局部视图中渲染模型实例,可以使用简写:
如果要在局部视图中自定义局部变量的名字,可以使用
:as
选项指定:The text was updated successfully, but these errors were encountered: