find 只能接數字,可以接特定數字 id (1)
或 id 列表 (1, 5, 6)
以及 id 數組 ([5, 6, 10])
,出現錯誤時會噴出 ActiveRecord::RecordNotFound 的錯誤。
假設我資料表內只有 2 筆資料
當我在網頁上搜尋超過我資料表筆數的資料
這時就會出現 ActiveRecord::RecordNotFound 的錯誤
find_by 可以接除了數字以外的參數,且只會找與指定條件匹配的第一條記錄,找不到會出現 nil,不會出現 ActiveRecord::RecordNotFound 的錯誤。
find_by! 可以接除了數字以外的參數,且只會找與指定條件匹配的第一條記錄,與 find_by 唯一的差異是,錯誤會出現 ActiveRecord::RecordNotFound 的錯誤。
如果你只有這個 action 要找資料就放在 action 裡,設定有找到就秀出來,沒有就轉到首頁。
def show
begin
@book = Book.find(params[:id])
rescue
redirect_to "/books"
end
end
如果你這個 controller 裡有很多 action 都要用到,就把它設定為一個方法,並在 controller 的一開始就告知,當出現 ActiveRecord::RecordNotFound 時就找:render_to 的方法,而這個方法是將網頁轉往首頁。
rescue_from ActiveRecord::RecordNotFound, with: :render_to
private
def render_to
redirect_to "/blogs"
end
當你有很多 controller 都有這個需求時,就把它放到所有 controller 的上一層 ApplicationController 去設定,這樣設定完成後每個 controller 都可使用這個方法。而當出現找不到時比較好的做法是,明確告知沒有這筆資料,所以找不到的時候設定 404 網頁是一個比較好的做法。
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :render_to
def render_to
render file: "{Rails.root}/public/404.html",
layout: false,#不要套版
status: 404 #狀態改404,不然網頁只是正常渲染會是200成功
end
end