你好,我是富士大顆 Aiko
今天來談談比較單純的題目: render
和 redirect_to
以下是 render
與 redirect_to
不同之處:
差異 | render | redirect_to |
---|---|---|
HTTP request | 在同一個週期內 | 發出一個新的 request |
URL 變化 | 不變 | 會改變 |
傳遞變數 | 可以將 Controller 中的實例變數傳遞到 View | 需要使用 session 或 URL 參數 |
效能 | 較好,因為沒有額外的 HTTP 請求 | 較差,因為需要一個額外的 HTTP request |
主要用途 | 主要用於渲染特定的 View | 將 user 導到不同的route 或外部 URL |
狀態碼 | 通常是 200 OK | 通常是 302 Found |
常見的 render
用法:
def show
@article = Article.find(params[:id])
render :show
end
render :show 會將 @article 實例變數渲染到對應的 show View 檔案。
(檔案路徑會是 app/views/[控制器名稱的複數形式]/show.html.erb。在這個例子中,就是 app/views/articles/show.html.erb。)
render
尤其在表單送出失敗時很有用,因為可以直接將錯誤信息渲染 View 中。保留 user 所填的資料,而不換頁:
def show
@article = Article.find(params[:id])
respond_to do |format|
format.html { render :show }
format.json { render json: @article }
end
end
除此之外,render
還有一些其他常見用法:
render "articles/show"
會渲染在 articles
目錄下名為 show
的樣式。def show
@article = Article.find(params[:id])
render "articles/show"
end
會尋找 app/views/articles/show.html.erb 並渲染它
def show
@book = Book.find(params[:id])
render 'books/show'
end
這會渲染在 app/views/books/show.html.erb 的樣式,即使這個 show 方法不是 BooksController 的 action。
def show
render plain: "OK"
end
render plain: "OK"
會直接回傳一個純文字 "OK"。
def show
@article = Article.find(params[:id])
render json: @article
end
render json: @article
會將 @article
物件轉為 JSON 格式並回傳。
def show
render status: 404
end
render status: 404
會設定 HTTP 狀態碼為 404。
def index
@products = Product.all
render inline: "<% @products.each do |p| %> <p><%= p.name %></p> <% end %>"
end
類似 inline style 的概念,使用嵌入在控制器中的 ERB 樣式來渲染。
respond_to
來根據請求類型(如 HTML、XML、JSON 等)渲染不同的內容。def show
@article = Article.find(params[:id])
respond_to do |format|
format.html { render :show }
format.json { render json: @article }
end
end
HTML 請求: 當客戶端請求 HTML 格式(通常是瀏覽器)時,會執行 format.html { render :show },這會渲染 show.html.erb 這個 View。
JSON 請求: 如果客戶端發出 JSON 請求(可能是 API 請求或 Ajax 請求),會執行 format.json { render json: @article },這會將 @article 物件轉換為 JSON 格式並回傳。
所以可以在同一個控制器的 Action 中處理多種不同格式的請求,這對於建立支持多種客戶端(如網站、手機應用程式等)的應用程式非常有用。
例如,你的網站前端可能會發出 HTML 請求以讀取網頁,而手機應用程式則可能會發出 JSON 請求。使用 respond_to,就能在同一個 Controller 動作中同時處理這兩種請求。
使用 redirect_to 常常是因為某些操作需要一個新的請求週期來完成,例如新增、更新或刪除資料後導向到不同的頁面。
常見的 redirect_to
用法
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render :new
end
end
1. 透過 URL 參數
最簡單的方法是將變數新增到 URL 參數中。這種方法適用於簡單和不敏感的資料。
#ArticlesController
def create
@article = Article.new(article_params)
if @article.save
redirect_to article_path(@article, foo: 'bar', baz: 'qux')
else
render :new
end
end
這樣會導向一個 URL 類似於 /articles/1?foo=bar&baz=qux
,然後你可以在目標控制器(Target Controller)中使用 params[:foo]
和 params[:baz]
來得到這些值。目標控制器指的是 redirect_to
所指向的控制器,在這個例子就會是 Article#show ,因為 create
完之後根據 RESTful 會是到該文章的 show,這個 id 參數是從 @article 物件中取得的。這裡的 @ariticle = @article.to_param(通常就是回傳 id) = @article.id。
2. 使用 Session
對於更為複雜或敏感的資料,你可以使用 session。Session 是一個用於儲存 user 特定資料的 Ruby Hash。可以在其中存放變數,然後在 redirect_to
之後的請求中讀取它。
def create
@article = Article.new(article_params)
if @article.save
session[:article_id] = @article.id
redirect_to @article
else
render :new
end
end
def show
@article = Article.find(session[:article_id])
# 其他邏輯
end
注意:由於 session 使用 cookie 來保存資料,因此不適用於大量或敏感資訊。
3. 使用 Flash
Flash 是一個特殊的部分 session,用於儲存會在下一個請求中消失的訊息。它通常用於像是成功或錯誤這樣的短暫訊息。
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article, notice: "文章已成功儲存。
else
render :new
end
end
然後,在 View 中,可以這樣顯示這個訊息
(如果只寫在 controller 那只會儲存在 flash 裡,而不會顯示出來):
<%= flash[:notice] %>
複習一下,就是這張圖
可以參考這篇
請求週期的長度會因應不同的情況而有所變化。它不是一個固定的時間單位,而是由多個因素影響的一個過程。以下是一些影響請求週期長度的因素:
網路連線品質:客戶端與伺服器之間的網路若延遲會影響 request 和 response 的時間。
伺服器效能:伺服器硬體和軟體的效能,以及當前負載(loading)狀況,都會影響處理請求的速度。
資料庫查詢:如果請求牽涉到資料庫操作,查詢效率和資料庫效能也會影響週期時間。
第三方服務:如果請求需要與第三方服務(例如 API)互動,這些服務的 response 時間也會影響整體的請求週期。
客戶端處理速度:某些請求週期也包括客戶端(如瀏覽器)渲染頁面的時間,這取決於 user 所使用裝置的效能。
程式碼效率:伺服器和客戶端程式碼的效率也會影響請求週期的長度。
由於這些多變因素,請求週期可能從幾毫秒到幾秒不等,甚至更長。在某些特殊情況下(例如文件上傳或大規模資料處理),它甚至可能需要更多時間。因此,沒有固定的「請求週期有多長」的答案。如果你希望優化請求週期,通常需要從多個層面來進行優化和調整。
狀態碼是 HTTP response 的一部分,用於表示請求的處理狀態。它是一個三位數的數字,通常與一個簡短的文字描述(狀態文字)一起出現,以說明請求成功、失敗,或需要進一步的操作。
這是一個表示成功的狀態碼。當 HTTP 請求成功被伺服器處理後,通常會返回 200 OK
。這意味著請求的資源已被成功讀取、新增、修改等。
這是一個重導(Redirection)狀態碼。當遇到這個狀態碼時,客戶端會被告知所請求的資源存在於一個不同的 URL 上,並且應該使用 GET 方法從那個 URL 重新獲取資源。這種狀態碼通常用於臨時的 URL 重導上。與之相對的是永久重導,通常使用 HTTP 狀態碼 301 Moved Permanently。表示資源已經永久地移動到了一個新的位置,並且未來都會在那裡。
簡而言之,200 OK
通常表示「一切正常,你的請求已成功」,而 302 Found
則表示「你要找的資源在別的地方,請從那裡重新讀取」。
以上!希望大家都有一些心得或想法了
gogogogogogo~~~~~~