General rescue throughout controller when id not found - RoR

后端 未结 4 1910
野的像风
野的像风 2021-02-07 11:21

I have stumbled upon a situation where my application looks for an id that does not exist in the database. An exception is thrown. Of course, this is a pretty standard situation

相关标签:
4条回答
  • 2021-02-07 11:51

    You must use rescue_from for this task. See example in the Action Controller Overview Guide

    class ApplicationController < ActionController::Base
      rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
    
      private
    
      def record_not_found
        redirect_to action: :index
      end
    end
    
    0 讨论(0)
  • 2021-02-07 11:55

    Rails has a built-in rescue_from class method:

    class CustomersController < ApplicationController
      rescue_from ActiveRecord::RecordNotFound, with: :index
      ...
    end
    
    0 讨论(0)
  • 2021-02-07 11:58

    In certain cases, I would recommend that you use Model.find_by_id(id) as opposed to Model.find(id). Instead of throwing an exception, .find_by_id returns nil. if the record could not be found.

    Just make sure to check for nils to avoid NoMethodError!

    P.S. For what it's worth, Model.find_by_id(id) is functionally equivalent to Model.where(id: id), which would allow you to build out some additional relations if you want.

    0 讨论(0)
  • 2021-02-07 12:08

    If you're talking about doing this within a single controller (as opposed to doing this globally in every controller) then here are a couple options:

    You can use a before_filter to setup your resource:

    class CustomerController < ApplicationController
      before_filter :get_customer, :only => [ :show, :update, :delete ]
    
      def show
      end
    
      private
    
      def get_customer
        @customer = ActiveRecord.find(params[:id])
        rescue ActiveRecord::RecordNotFound
          redirect_to :action => :index
      end
    end
    

    Or you might use a method instead. I've been moving in this direction rather than using instance variables inside views, and it would also help you solve your problem:

    class CustomerController < ApplicationController
      def show
        # Uses customer instead of @customer
      end
    
      private
    
      def customer
        @customer ||= Customer.find(params[:id])
        rescue ActiveRecord::RecordNotFound
          redirect_to :action => :index
      end
      helper_method :customer
    end
    
    0 讨论(0)
提交回复
热议问题