17

Я получил следующее сообщение об ошибке:rescue_from ActionController :: RoutingError в Rails 4

ActionController::RoutingError (No route matches [GET] "/images/favicon.ico") 

Я хочу показать error404 страницу для ссылки, которые не существующих.

Как я могу это достичь?

ответ

51

В application_conroller.rb добавить следующее:

# 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 

Я обычно также спасти следующие исключения, но это до вас:

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

Создание контроллера ошибок:

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

Тогда в 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 

И последняя вещь, чтобы создать not_found.html.haml (или любой другой механизм шаблонов вы используете) под /views/errors/:

%span 404 
    %br 
    Page Not Found 
+4

Это не работает в Rails 4.2.5. Я предполагаю, что это связано с тем, что исключение возникает ActionDispatch до запуска любого кода контроллера. – depquid

+0

@depquid Я написал его во времена Rails 4.0.x, но только что протестировал его с Rails 4.2.5. Я полагаю, вы не добавили маршрут и не создали 'errors_controller.rb' :) Если это так - пожалуйста, не забудьте убрать нижний план, если у вас нет причин оставлять его –

+6

Извините, я не настроил маршрут правильно. Но почему, 'rescue_from ActionController :: RoutingError, с: -> {render_404}', если вы направляетесь непосредственно к действию? – depquid

2

я получаю эту ошибку. Я скопировал favicon image в app/assets/images и его работу для меня.

-2

@ Андреа Дейнеко, ваше решение, похоже, работает только для RoutingError s, поднятых вручную внутри conrtoller. Если я попробую с url my_app/not_existing_path, я до сих пор получаю стандартное сообщение об ошибке.

Я думаю, это связано с тем, что приложение даже не доходит до контроллеров, так как Rails вызывает ошибку раньше.

The trick, что решить эту проблему для меня, чтобы добавить следующую строку в конце маршрутов:

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

поймать все не предопределенные запросы.

Тогда в ErrorsController вы можете использовать respond_to служить HTML, JSON ... запросы:

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

Не могли бы вы объяснить '@requested_path = request.path' и соответствующий ему вызов' format.json {render json: {routing_error: @requested_path}} '? –

+0

Я только что использовал '@ requested_path' в шаблоне (error_404.html.haml). Что касается json, если я уверен, что мне не нужна полная страница, возвращаемая, например, ajax, я могу попросить json вернуться и получить сообщение об ошибке – Misu

Смежные вопросы