Trả lời

51

Trong application_conroller.rb thêm như sau:

# You want to get exceptions in development, but not in production. 
    unless Rails.application.config.consider_all_requests_local 
    rescue_from ActionController::RoutingError, with: -> { render_404 } 
    end 

    def render_404 
    respond_to do |format| 
     format.html { render template: 'errors/not_found', status: 404 } 
     format.all { render nothing: true, status: 404 } 
    end 
    end 

Tôi thường cũng giải cứu ngoại lệ sau đây, nhưng đó là tùy thuộc vào bạn:

rescue_from ActionController::UnknownController, with: -> { render_404 } 
rescue_from ActiveRecord::RecordNotFound,  with: -> { render_404 } 

Tạo bộ điều khiển lỗi:

class ErrorsController < ApplicationController 
    def error_404 
    render 'errors/not_found' 
    end 
end 

Sau đó, trong routes.rb

unless Rails.application.config.consider_all_requests_local 
    # having created corresponding controller and action 
    get '*path', to: 'errors#error_404', via: :all 
    end 

Và điều cuối cùng là tạo ra not_found.html.haml (hoặc bất kỳ template engine bạn sử dụng) dưới /views/errors/:

%span 404 
    %br 
    Page Not Found 
+4

này không hoạt động trong Rails 4.2.5. Tôi đoán đó là bởi vì ngoại lệ được nâng lên bởi ActionDispatch trước khi bất kỳ mã điều khiển nào được chạy. – depquid

+0

@ depquid Tôi đã viết nó trong thời gian của Rails 4.0.x, nhưng đã thử nghiệm nó với Rails 4.2.5 - Tôi cho rằng bạn không thêm tuyến đường và không tạo ra 'errors_controller.rb' :) Nếu đó là trường hợp - hãy chắc chắn rút lại phiếu giảm giá, trừ khi bạn có nhiều lý do để hủy bỏ số này –

+6

Rất tiếc, tôi đã không thiết lập đúng tuyến đường. Nhưng tại sao có 'rescue_from ActionController :: RoutingError, với: -> {render_404}' nếu bạn định tuyến trực tiếp đến hành động? – depquid

2

tôi đã nhận được lỗi này. Tôi đã sao chép hình ảnh favicon favicon trong app/assets/images và nó hoạt động cho tôi.

-2

@Andrey Deineko, giải pháp của bạn dường như chỉ hoạt động đối với số RoutingError được nâng lên thủ công bên trong conrtoller. Nếu tôi thử với url my_app/not_existing_path, tôi vẫn nhận được thông báo lỗi chuẩn.

Tôi đoán điều này là do ứng dụng thậm chí không đạt được bộ điều khiển, vì Rails tăng lỗi trước đây.

Các trick rằng giải quyết vấn đề đối với tôi là để thêm dòng sau vào cuối các tuyến đường:

Rails.application.routes.draw do 
    # existing paths 
    match '*path' => 'errors#error_404', via: :all 
end 

để bắt yêu cầu tất cả không được xác định trước.

Sau đó, trong ErrorsController bạn có thể sử dụng để phục vụ respond_to html, json ... yêu cầu:

class ErrorsController < ApplicationController 
    def error_404 
    @requested_path = request.path 
    repond_to do |format| 
     format.html 
     format.json { render json: {routing_error: @requested_path} } 
    end 
    end 
end 
+0

bạn có thể giải thích '@requested_path = request.path' và lệnh tương ứng' format.json {render json: {routing_error: @requested_path}} 'không? –

+0

Tôi vừa mới sử dụng '@ requested_path' trong mẫu (error_404.html.haml). Đối với các json, nếu tôi chắc chắn tôi không muốn một trang đầy đủ trở lại, ví dụ bằng ajax, tôi có thể yêu cầu json trả lại, và nhận được thông báo lỗi – Misu

Các vấn đề liên quan