1. 程式人生 > >(Go rails)使用Rescue_from來更好的解決404❌

(Go rails)使用Rescue_from來更好的解決404❌

https://gorails.com/episodes/handle-404-using-rescue_from?autoplay=1

Handle 404s Better Using Rescue_from

在controller層新增resuce_from方法。對ActiveRecord::RecordNotFound❌進行營救。

 

當用戶拷貝連結錯誤或者其他導致錯誤的url,網頁會彈出一個404.

 

Well, if we couldn't find the episode, or the forum thread or whatever they were looking for, if we can't find it directly with the perfect match, then we should take that and search the database and clean it up a little bit, but then go search the database。


 

class Episode < ApplicationRecord
  def to_param
    slug
  end
end

在controller中:

private

  def set_episode
    //find_by! 如果沒有找到匹配的記錄會raise an ActiveRecord::RecordNotFound
    @episode = Episode.find_by!(slug: params[id])
  end

  def episode_params
    params.require(:episode).permit(:name, :slug)
  end

 

輸入了錯誤的網址episodes/text, (正確的是episodes/text-1)

導致出現❌

 

在controller:

class EpisodesController <ApplicationController
  before_action :set_episode, only: [:show, :edit, :update, :destroy]

  rescue_from ActiveRecord::RecordNotFound do |exception|
    byebug   //一個用於debug的gem中的方法,rails預設新增的
end
end

 

再重新整理錯誤網頁,然後看terminal的fservent_watch:

輸入:

 

class EpisodesController <ApplicationController
  before_action :set_episode, only: [:show, :edit, :update, :destroy]

  rescue_from ActiveRecord::RecordNotFound do |exception|
     @episodes = Episode.where("slug LIKE ?", "%#{params[:id]}%")
     render "/search/show"
  end
end

 

新增一個views/search/show.html.erb

<h3>很抱歉,您要訪問的頁面不存在!</h3>
<% if @episodes.any? %>   <p>這裡有一些相似的結果:</p>   <% @episodes.each do |episode| %>    <div>    <%= link_to episode.name, episode %>    </div>   <% end %>
<% else %>
<%= link_to "Check out all our episodes", episodes_path %>
<% end %>

 

進一步完善功能:加上 

class EpisodesController <ApplicationController
  before_action :set_episode, only: [:show, :edit, :update, :destroy]

  rescue_from ActiveRecord::RecordNotFound do |exception|
     @query = params[:id].gsub(/^[\w-]/, '')
     @episodes = Episode.where("name LIKE ? OR slug LIKE ?", "%#{@query}%", "%#{@query}%")
     render "/search/show"
  end
end

可以把recue_from放到一個單獨的模組SearchFallback中:

把這個模組放入app/controllers/concern/search_fallback.rb中:

module SearchFallback
//因為included方法是ActiveSupport::Concern模組中的方法,所以extend這個模組,就能用included了 extend ActiveSupport::Concern //當這個模組被類包含後,則: included do rescue_from ActiveRecord::RecordNotFound do
|exception|   @query = params[:id].gsub(/[^\w-]/, '')    @episodes = Episode.where("name LIKE ? OR slug LIKE ?", "%#{@query}%", "%#{@query}%")    @forum_threads = Episode.where("name LIKE ? OR slug LIKE ?", "%#{@query}%", "%#{@query}%")    render "/search/show" end end end

 

然後EpisodesController, include SearchFallback