Ruby on Rails: How do I change the behavior of RecordNotFound?

匿名 (未验证) 提交于 2019-12-03 08:52:47

问题:

When going to on object's show page with an id that doesn't exist, the RecordNotFonud exception is thown. Is there a way I can redirect to some error page, or maybe a different action when this error is thrown?

回答1:

You may use rescue_from if you are using Rails 3:

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

Yes, you can also do a redirect instead of render, but this is not a good idea. Any semi-automatic interaction with your site will think that the transfer was successfull (because the returned code was not 404), but the received resource was not the one your client wanted.



回答2:

In development mode you'll see the exception details but it should automatically render the 404.html file from your public directory when your app is running in production mode.



回答3:

See http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html. Rails has nice features for exception handling.



回答4:

I generally do something like this in my 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


回答5:

If you need to handle more than one specific exception, use rescue_action or rescue_action_in_public, the difference in to hook local requests or not (development/production in common). I prefer to use in_public , because need to review exception's backtrace in development mode.

take a look at my source code:

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


回答6:

Use a begin - rescue - end construct to catch the exception and do something useful with it.

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!