Подтвердить что ты не робот

Rails 4: Как создать пользовательскую страницу 404, использующую конвейер активов?

Существует множество решений для создания настраиваемых страниц обработки ошибок, но почти для Rails 4:

Стандартный ответ поощрения людей к изменению 404.html в /public не работает для меня, потому что я хочу использовать тему CSS, которая находится в конвейере активов. Есть ли способ, с помощью которого html файлы могут обращаться к тем стилям, определенным в конвейере ресурсов? Если нет, существует способ создания настраиваемого обработчика ошибок, который имеет доступ к конвейеру?

4b9b3361

Ответ 1

Для Rails 4.1 мне нравится этот ответ, добавьте тип актива лучше; однако я не пробовал. В Rails 4.0.8 эти три рекомендации помогли мне:

  • Страницы динамической ошибки - вторая ссылка в вопросе. Это сработало для меня отлично.

  • Пользовательские страницы ошибок, возможно, были вырезаны из первой ссылки или наоборот, но идет дополнительная миля, добавив некоторые информация о тестировании с Capybara.

  • Я не тестировал Capybara, потому что я не хотел менять тестовую конфигурацию; однако Спецификации запросов RSpec-Rails помогли мне проверить эти запросы самостоятельно и убедиться, что они заполняют и возвращают правильный контент.

Далее следует краткое описание того, чему учат три ссылки:

  • Добавьте следующую настройку в config/environments/production.rb

    # Route exceptions to the application router vs. default
    config.exceptions_app = self.routes
    
  • Отредактируйте конфигурацию маршрутизации, config/routes.rb, чтобы направить страницы ошибок на контроллер ошибок

      # error pages
      %w( 404 422 500 503 ).each do |code|
        get code, :to => "errors#show", :code => code
      end
    

    перенаправляет запросы страницы 404, 422, 500 и 503 к действию show контроллера errors с параметром code, который имеет значение кода состояния.

  • Создайте контроллер, app/controllers/errors_controller.rb. Вот весь контент:

    class ErrorsController < ApplicationController
    
      def show
        status_code = params[:code] || 500
        flash.alert = "Status #{status_code}"
        render status_code.to_s, status: status_code
      end
    
    end
    

    Мое предпочтение состояло в том, чтобы установить сообщение состояния на flash.alert

  • Создайте сами страницы. Я использую .erb Здесь app/views/errors/500.html.erb

    <p>Our apology.  Your request caused an error.</p>
    <%= render 'product_description' %>
    

    Итак, вы видите, что вы можете сделать частичное. Страница отображает весь шаблон шаблона от app/views/layouts/application.html.erb или любой другой шаблон шаблона компоновки, который вы настроили. Это включает в себя <div id='alert'><%= alert %></div>, который отображает сообщение о состоянии со вспышки.

  • Протестировано с помощью RSpec, добавив тестовый файл, spec/requests/errors_request_spec.rb. Ниже приведен сокращенный контент этого файла, который показывает тест на странице состояния 500:

    require 'rails_helper'
    
    RSpec.describe "errors", :type => :request do
    
      it "displays the 500 page" do
        get "/500"
        assert_select 'div#alert', 'Status 500'
        assert_select 'div[itemtype]'
      end
    
    end
    

    Первое утверждение проверяет флеш-предупреждение. Второе утверждение проверяет частичное.

Ответ 2

Мы создали драгоценный камень, который делает это для вас: exception_handler.

Существует также отличный учебник здесь.

Я также написал обширный ответ на эту тему here.

Middleware

# config/application.rb
config.exceptions_app = ->(env) { ExceptionController.action(:show).call(env) }

контроллер

# app/controllers/exception_controller.rb
class ExceptionController < ApplicationController
  respond_to :json, :js, :html
  before_action :set_status

  def show
    respond_with @status
  end

  private

  def set_status
    def status
      @exception = env['action_dispatch.exception']
      @status    = ActionDispatch::ExceptionWrapper.new(env, @exception).status_code
      @response  = ActionDispatch::ExceptionWrapper.rescue_responses[@exception.class.name]
    end
  end
end

Просмотр

# app/views/exception/show.html.erb
<h1>404 error</h1>

Это очень простая версия - я могу объяснить больше, если вы пожелаете.

В принципе, вам нужно подключиться к config.exceptions_app промежуточному программному обеспечению, он будет захватывать любое исключение в стеке middleware (в отличие от для рендеринга всей среды), позволяя вам отправить запрос на свой собственный controller#action.

Если вы прокомментируете, я поможем вам еще, если вы захотите!