Rails,开发环境和错误页面

yaz*_*yaz 2 development-environment http-status-code-404 ruby-on-rails-3

我做了一个简单的应用程序,我想测试404,500等http页面的错误.我已经在我的环境/ development.rb中将config.consider_all_requests_local更改为false但我仍然遇到了一些问题,所以我想问你几个问题......

  1. 如果我输入不合适的东西,就像http://localhost:3000/products/dfgdgdgdgfd我仍然看到旧的"未知行动"网站.但是,如果我输入我的电脑的本地IP地址.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
Run Code Online (Sandbox Code Playgroud)

...但该代码在任何情况下都不起作用.

2.2.第二个解决方案是放置match "*path" , :to => "products#show", :id=>1(这是我的愚蠢应用程序中的示例主页)或match "*path" , :to => "errors#error_404", :id=>1routes.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 
Run Code Online (Sandbox Code Playgroud)

这非常有用,因为它可以让我渲染动态erb文件但是......它不会呈现任何布局.我试图改变body = template.render(:file => file),body = template.render(:partial => file, :layout => "layouts/application")但它只是惹恼了错误.

我知道我做错了,我相信这些错误页面有一个可行的解决方案,所以我希望你能帮忙......

干杯.

yaz*_*yaz 5

在您的应用程序控制器中,您需要覆盖此方法:

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

然后你必须将它与这个代码结合起来:

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
Run Code Online (Sandbox Code Playgroud)