Rails, env разработки и страницы ошибок - PullRequest
2 голосов
/ 06 мая 2011

Я сделал простое приложение и хотел проверить страницы на наличие ошибок 404, 500 и т. Д. Http. Я изменил config.consider_all_requests_local на false в моем enviroments / development.rb, но у меня все еще есть некоторые проблемы, поэтому я хотел бы задать вам несколько вопросов ...

  1. Если я вписываю в свой баузер что-то неуместное, например http://localhost:3000/products/dfgdgdgdgfd, я все равно вижу старый сайт "Неизвестное действие". Однако, если я наберу локальный IP-адрес моего компьютера для ex. http://192.168.1.106:3000/products/dfgdgdgdgfd Я вижу страницу ошибки 404 из общей папки. Почему это происходит?

  2. Я знаю, что если я разверну свой маленький проект где-нибудь, тогда мое приложение будет использовать рабочий режим, и если произойдет какая-либо ошибка, появится страница 404 или 500. Но что, если я хочу сделать эти страницы ошибок более динамичными (например, при отображении сообщения об ошибке при использовании макета со списком популярных продуктов) или просто перенаправить их на главную страницу?

2,1. Первым решением, которое я нашел, было использование метода rescue_from в контроллере приложения:

unless Rails.application.config.consider_all_requests_local
   rescue_from Exception, :with => :render_error
   rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
   rescue_from AbstractController::ActionNotFound, :with => :render_not_found
   rescue_from ActionController::RoutingError, :with => :render_not_found
   rescue_from ActionController::UnknownController, :with => :render_not_found
   rescue_from ActionController::UnknownAction, :with => :render_not_found
end
.
.
.
private
def render_error exception
  Rails.logger.error(exception)
  redirect_to root_path
  #or 
  # render :controller=>'errors', :action=>'error_500', :status=>500
end

def render_not_found exception
  Rails.logger.error(exception)
  redirect_to root_path
  #or 
  # render :controller=>'errors', :action=>'error_404', :status=>404
end

... но этот код не работал ни в коем случае.

2,2. Второе решение состояло в том, чтобы поместить match "*path" , :to => "products#show", :id=>1 (это пример главной страницы моего глупого приложения) или match "*path" , :to => "errors#error_404", :id=>1 в конце файла rout.rb. Этот код работает только для опечаток, таких как http://192.168.1.106:3000/dfgdgdgdgfd, потому что если я попробую http://192.168.1.106:3000/products/dfgdgdgdgfd (контроллер существует, но действие не найдено), я все равно получаю страницу 404. Я играл немного, пытаясь что-то вроде match "*path/*act" , :to => "products#show", :id=>1 или match ":controller(/*act)" , :to => "products#show", :id=>8, но это тоже не сработало ...

2,3. Третьим решением было создать контроллер для ошибок и файл в папке инициализаторов с таким кодом:

# initializers/error_pages.rb
module ActionDispatch 
  class ShowExceptions 
    protected     
    def rescue_action_in_public(exception) 
       status = status_code(exception).to_s 
       template = ActionView::Base.new(["#{Rails.root}/app/views"]) 
       if ["404"].include?(status) 
         file = "/errors/404.html.erb" 
       else 
         file = "/errors/500.html.erb" 
       end         
       body = template.render(:file => file) 
       render(status, body) 
    end 
  end 
end 

Это было довольно полезно, потому что это позволило бы мне рендерить динамические файлы erb, но ... это не рендеринг любого макета. Я пытался изменить body = template.render(:file => file) на body = template.render(:partial => file, :layout => "layouts/application"), но это были только ошибки корпуса.

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

Приветствие.

1 Ответ

5 голосов
/ 11 мая 2011

В вашем контроллере приложения вам нужно переопределить этот метод:

def method_missing(m, *args, &block)
  Rails.logger.error(m)
  redirect_to :controller=>"errors", :action=>"error_404"
  # or render/redirect_to somewhere else
end

, а затем вы должны объединить его с этим кодом:

unless Rails.application.config.consider_all_requests_local
  rescue_from Exception, :with => :method_missing
  rescue_from ActiveRecord::RecordNotFound, :with => :method_missing
  rescue_from AbstractController::ActionNotFound, :with => :method_missing
  rescue_from ActionController::RoutingError, :with => :method_missing
  rescue_from ActionController::UnknownController, :with => :method_missing
  rescue_from ActionController::UnknownAction, :with => :method_missing
end
...