Ostatnimi dniami wzięło mnie na poprawianie moich repo na githubie. Jednym z pluginów do poprawy był mój niewielki Custom Errors Handler, który ma za zadanie generować odpowiedni szablon błędu zależnie od miejsca w którym wystąpił błąd. Dzięki temu, np. moduł administracji może mieć inne 404 niż moduł użytkowników.

Cały kod składa się z dwóch klas:

  • MyActionDispatch::ShowExceptions
  • CustomErrorsHandlerController

Pierwsza z nich to middleware odpowiedzialny za przejmowanie obsługi wyświetlania wyjątków, drugi to kontroler który ma wygenerować widok.

W cały kod wgłębiać się nie będę (jest dostępny na moim githubie), opiszę jednak proces dodawania middlewaru z poziomu gemu dedykowanego dla Railsów. Dawniej był plik init.rb, w którym można było najzwyczajniej nadpisać domyślny ActionDispatch::ShowExceptions. Takie podejście w Railsach3 jednak nie przejdzie (chociaż póki co, jako plugin działa ;) ). Aby móc nasz middleware wykorzystać zamiast domyślnego, posłużymy się metodą swap middleware'u (o innym metodach z rodziny middleware'u przeczytasz tutaj).

Zamiana jest całkiem prosta:

  class Railtie < Rails::Railtie
    initializer "app.insert_my_errors_handler" do |app|
      app.config.middleware.swap ActionDispatch::ShowExceptions, 
        MyActionDispatch::ShowExceptions
    end
  end

Podajemy co zamieniamy i na co, pamiętając przy tym, że init.rb już nie jest wywoływany, więc ten kod powinien trafić do /lib/nazwa_gema.rb.

Pamiętajmy też, że jeżeli chcemy mieć kompletnie niezależny kontroler - nie powinien on dziedziczyć po ApplicationControlerze, ale raczej bezpośrednio po ActionController::Base, dzięki czemu nie będzie zależny od filtrów nałożonych na ApplicationController.