[Rails]Rails中render常見的用法(1)
這篇筆記會聚焦render在controller中的常見用法。
預設render同名的view
在Rails中contoller中會預設去render與路由同名的view。舉例來說,當你在PagesController的index action中,即便你不指定render的view,Rails也會自動幫你找尋模板
class PagesController < ApplicationController
def index
@pages = Page.all
# render :new
# 即使沒有render,Rails也會自動幫你抓取app/views/pages/index.html.erb的模板
end
end
render同一個controller下的template
以下的程式碼代表的是,當update不成功時,render同一個controller下的edit template
class PagesController < ApplicationController
def update
@page = Page.find(params[:id])
if @page.update(page_params)
redirect_to page_path(@page)
else
render :edit
# 用途跟render temlate: :edit一樣
end
end
end
render其他contoller的view
如果想要
像是categories controller下的index template的話,可以這樣做
class PagesController < ApplicationController
def index
@pages = Page.all
render "categories/index"
# 路徑會是相對於app/view
end
end
render使用inline選項
我們可以使用inline的選項,讓我們不使用view的模板,而是使用提供的一段erb程式碼
# app/controllers/pages_controller.rb
def index
pages = Page.all
render inline: "<% pages.each do |p| %><%= p.user %>
<% end %>"
end
頁面產生,
雖然透過inline選項,可以將erb程式碼放在controller中render,但是實務上很少這麼做。
因為這種做法等於是在controller中混用了view,跟Rails的MVC原則相衝突,基本上還是會把要render的內容拉到模板中。
render純文字(plain)
如果只想要render純文字,可以透過plain選項
# app/controllers/pages_controller.rb
def index
pages = Page.all
render plain: "安安,我是純文字"
end
可以得到
當我們使用plain時,連預設的版型(layout)都不會使用。如果需要使用layout的話,記得加上layout: true
# app/controllers/pages_controller.rb
def index
pages = Page.all
render plain: "安安,我是純文字", layout: true
end
render json
如果要render json的話,可以使用json option,並將想要傳遞的object透過實體變數傳入。
# app/controllers/pages_controller.rb
def index
@pages = Page.all
render json: @pages
end
這樣會得到
這邊值得注意的是不需要對要render的object呼叫 to_json。因為:json選項會試射自動對object呼叫 to_json方法。
render和redirect_to的不同
render告訴Rails要用那個View或是其他 Asset)。而redirect_to則是告訴瀏覽器對不同的URL發一個新請求。舉例來說,可以在程式碼任何一個地方做轉址,比如轉到 photos的index就會是
redirect_to photos_path
不過需要注意的是
一個action中只能有一個render或redirect_to,不然你會得到一個DoubleRenderError例外錯誤。
避免render多次
在上一段我們有提到,一個action中只能有一個redirect_to或render。如果你在同一個controller中render多次的話,
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show"
end
render action: "regular_show"
end
你可能會得到以下的錯誤訊息
上面那段程式碼會出錯的原因是,當@book.special?為true時,會先render
special_show接著再去render regular_show。當一個controller render多次時就會出現錯誤。
解決方法就是讓action只出現一次render或action。如果真的要使用多次,那要加上and return來離開目前的action。
使用and return
多個render
def show
@book = Book.find(params[:id])
if @book.special?
render action: "special_show" and return
end
render action: "regular_show"
end
redirect_to和render同時存在
def show
@book = Book.find(params[:id])
if @book.special?
redirect_to root_path
end
render action: "regular_show"
end
各種同樣效果的render寫法
以下幾種寫法均能render app/views/books/edit.html.erb這個template。
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"
參考資料
Rails 算繪與版型
Layout, Render 與 View Helper
Rails學習推薦書籍
Leave [Rails]Rails中render常見的用法(1) to:
Read more #cn posts
Best Posts From linjiahung
We have not curated any of linjiahung's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.