Ruby on Rails:如何更改RecordNotFound的行为?

当转到具有不存在的id的对象的显示页面时,会抛出RecordNotFonudexception。 有没有办法可以重定向到某个错误页面,或者在抛出此错误时可能有不同的操作?

如果您使用的是Rails 3,则可以使用rescue_from :

 class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, :with => :render_404 def render_404 respond_to do |format| format.html { render :action => "errors/404.html.erb", :status => 404 } # and so on.. end end end 

是的,您也可以进行重定向而不是渲染 ,但这不是一个好主意。 与您的站点进行的任何半自动交互都会认为传输是成功的(因为返回的代码不是404),但收到的资源不是您的客户想要的。

在开发模式下,您将看到exception详细信息,但当您的应用程序在生产模式下运行时,它应自动从您的公共目录呈现404.html文件。

请参阅http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html 。 Rails具有很好的exception处理function。

我通常在我的ApplicationController中做这样的事情

 class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, :with => :routing_error private def routing_error redirect_to(root_url, :alert => "Sorry, the page you requested could not be found.") end end 

如果您需要处理多个特定exception,请使用rescue_actionrescue_action_in_public ,区别于是否挂钩本地请求(开发/生产共同)。 我更喜欢使用in_public ,因为需要在开发模式下检查exception的回溯。

看看我的源代码:

 class ApplicationController < ActionController::Base include CustomExceptionsHandler .... end module CustomExceptionsHandler # Redirect to login/dashboard path when Exception is caught def rescue_action_in_public(exception) logger.error("\n !!! Exception !!! \n #{exception.message} \n") case exception.class.to_s when "Task::AccessDenied" logger.error(" !!! 403 !!!") notify_hoptoad(exception) //catch this kind of notification to Hoptoad render_403 when "AuthenticatedSystem::PermissionDenied" logger.error(" !!! 403 !!!") render_403 when "Task::MissingDenied" logger.error(" !!! 404 !!!") notify_hoptoad(exception) render_404 when "ActionController::RoutingError" logger.error(" !!! 404 !!!") render_404 else notify_hoptoad(exception) redirect_to(current_user.nil? ? login_path : dashboard_path) and return false end end private #403 Forbidden def render_403 respond_to do |format| format.html { render :template => "common/403", :layout => false, :status => 403 } format.xml { head 403 } format.js { head 403 } format.json { head 403 } end return false end #404 Not Found def render_404 respond_to do |format| format.html { render :template => "common/404", :layout => false, :status => 404 } format.xml { head 404 } format.js { head 404 } format.json { head 404 } end return false end end 

使用begin-rescue-end构造来捕获exception并使用它做一些有用的事情。

 userid=2 begin u=User.find userid rescue RecordNotFound redirect_to "/errorpage" #Go to erropage if you didn't find the record exit end redirect_to u # Go to the user page