22

Có nhiều giải pháp để tạo tùy chỉnh xử lý các trang lỗi, nhưng hầu như không ai cho Rails 4:Rails 4: Làm cách nào để tạo trang 404 tùy chỉnh sử dụng đường dẫn nội dung?

Câu trả lời tiêu chuẩn khuyến khích mọi người sửa đổi 404.html trong /public doesn' t làm việc cho tôi vì tôi muốn sử dụng chủ đề CSS nằm trong đường ống nội dung. Có cách nào để các tệp html có thể truy cập các kiểu được xác định trong đường ống nội dung không? Nếu không, có cách nào để tạo trình xử lý lỗi tùy chỉnh có quyền truy cập vào kênh không?

+0

Tôi nghĩ rằng tài liệu tham khảo thứ hai của bạn có những gì bạn muốn. ** nhưng hầu như không có gì cho Rails 4 **, bạn có chắc là tham chiếu thứ hai không hoạt động trên đường ray 4 không? Bạn đã làm gì? –

Trả lời

5

Chúng tôi đã tạo một viên ngọc để thực hiện điều này cho bạn: exception_handler.

Ngoài ra còn có hướng dẫn tuyệt vời here.

Tôi cũng đã viết một câu trả lời mở rộng về chủ đề here.

Middleware

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

khiển

# 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 

Xem

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

này là rất đơn giản versi on - Tôi có thể giải thích thêm nếu bạn muốn.

Về cơ bản, bạn cần phải móc vào phần mềm trung gian config.exceptions_app, nó sẽ nắm bắt bất kỳ ngoại lệ nào trong ngăn xếp middleware (trái với toàn bộ môi trường), cho phép bạn gửi yêu cầu đến controller#action của riêng bạn.

Nếu bạn nhận xét, tôi sẽ giúp bạn thêm một số chi tiết nếu bạn muốn!

+1

'class ExceptionController

+0

không liên quan gì đến phiên bản đường ray. đó là quy ước. Bộ điều khiển được gọi là 'NameController' và sau đó bạn đặt tên cho tệp' name_controller.rb'. Rails đang tìm kiếm một 'NameController'. Nếu bạn chỉ gọi nó là 'class Name', nó sẽ ném một' Unable to autoload constant NameController' (vì anh ta mong đợi NameController nhưng không thể tìm thấy nó) –

36

Dành cho Rails 4.1 Tôi thích this answer, add an asset type tốt hơn; tuy nhiên tôi chưa thử. Trên Rails 4.0.8, ba tài liệu tham khảo này đã giúp tôi:

  1. Dynamic error pages là tham chiếu thứ hai trong câu hỏi. Điều này làm việc tốt cho tôi.

  2. Custom error pages có thể đã được nôi từ tham chiếu đầu tiên hoặc cách khác, nhưng đi thêm dặm bằng cách thêm một số thông tin về thử nghiệm với Capybara.

  3. Tôi đã không thực hiện thử nghiệm Capybara vì tôi không muốn thay đổi cấu hình thử nghiệm; tuy nhiên, RSpec-Rails Request Specs đã xếp tôi vào để kiểm tra những yêu cầu này một cách độc lập và thấy rằng họ hoàn thành và trả lại nội dung chính xác.

Sau đây là một mô tả ngắn gọn về những gì được giảng dạy bởi ba tham khảo:

  1. Thêm các thiết lập sau đây để config/environments/production.rb

    # Route exceptions to the application router vs. default 
    config.exceptions_app = self.routes 
    
  2. Chỉnh sửa cấu hình định tuyến, config/routes.rb để hướng các trang lỗi đến bộ điều khiển lỗi

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

    sẽ định tuyến các yêu cầu trang 404, 422, 500 và 503 tới hành động show của bộ điều khiển errors với tham số code có giá trị của mã trạng thái.

  3. Tạo bộ điều khiển, app/controllers/errors_controller.rb. Dưới đây là toàn bộ nội dung:

    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 
    

    sở thích của tôi là để thiết lập một thông báo trạng thái trên flash.alert

  4. Tạo các trang bản thân. Tôi sử dụng .erb Đây là app/views/errors/500.html.erb

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

    Vì vậy, bạn thấy rằng bạn có thể làm cho một phần. Trang hiển thị với tất cả các bản mẫu bố cục từ app/views/layouts/application.html.erb hoặc bất kỳ bản mẫu bố cục nào khác mà bạn đã định cấu hình. Bao gồm <div id='alert'><%= alert %></div> hiển thị thông báo trạng thái từ đèn flash.

  5. Đã kiểm tra bằng RSpec bằng cách thêm tệp thử nghiệm, spec/requests/errors_request_spec.rb. Đây là nội dung viết tắt của tệp đó cho thấy bài kiểm tra của trang trạng thái 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 
    

    Kiểm tra xác nhận đầu tiên cho cảnh báo flash. Xác nhận thứ hai sẽ kiểm tra một phần.

+1

Chỉ có một vấn đề với giải pháp đường ống nội dung. Mỗi tập tin html là hậu tố với tiêu hóa và do đó làm cho nó khó tìm thấy từ Dispatcher :: PublicExceptions. Tôi khuyên mọi người nên thử cái được đề cập ở đây. – Kristoffer

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