Ruby on Rails - 造成ActiveRecord::RecordNotFound 的原因

差異

  1. find

    find 只能接數字,可以接特定數字 id (1)id 列表 (1, 5, 6) 以及 id 數組 ([5, 6, 10]),出現錯誤時會噴出 ActiveRecord::RecordNotFound 的錯誤。

    假設我資料表內只有 2 筆資料

    當我在網頁上搜尋超過我資料表筆數的資料

    這時就會出現 ActiveRecord::RecordNotFound 的錯誤

  2. find_by

    find_by 可以接除了數字以外的參數,且只會找與指定條件匹配的第一條記錄,找不到會出現 nil,不會出現 ActiveRecord::RecordNotFound 的錯誤。

  3. find_by!

    find_by! 可以接除了數字以外的參數,且只會找與指定條件匹配的第一條記錄,與 find_by 唯一的差異是,錯誤會出現 ActiveRecord::RecordNotFound 的錯誤。

解決出現 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
    
comments powered by Disqus