Home > Enterprise >  How can i catch not_found properly?
How can i catch not_found properly?

Time:01-13

Currently i am catching the error not_found like this

def show
            begin
              @task = Task.find(params[:id])          
            rescue ActiveRecord::RecordNotFound => e
              render json: { error: e.to_s }, status: :not_found and return     
            end

and the rspec test would be like this expect(response).to be_not_found but i dont want to do that (rescue ActiveRecord::RecordNotFound => e) in every single function (update, create, destroy and so on)

there is another way?

for example this way

rescue_from ActiveRecord::RecordNotFound, with: :not_found

                      def not_found
                        respond_to do |format|
                          format.json { head :not_found }
                        end
                      end  

but i dont know how can i test with that

i would like to test the same way

expect(response).to be_not_found

CodePudding user response:

I think that your original implementation with an error node is a better response but your modified change is a better way to handle so I would suggest combining the 2 concepts via

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :not_found

  private 
    def not_found(exception) 
      respond_to do |format| 
        format.json do 
          # I expanded the response a bit but handle as you see fit
          render json: {
            error: {
              message: 'Record Not Found', 
              data: { 
                 record_type: exception.model,
                 id: exception.id
               } 
            }
          }, status: :not_found 
      end 
    end 
end

You should be able to maintain your current test in this case while avoiding the need to individually handle in each request.

CodePudding user response:

You can add the below code in your application_controller.rb.

around_filter :catch_not_found #=> only:[:show, :edit]

def catch_not_found
  yield
rescue ActiveRecord::RecordNotFound => e
  respond_to do |format|
   format.json { render json: { error: e.to_s }, status: :not_found and return   } 
   format.html { redirect_to root_url, :flash => { :error => "Record not found." } and return }
  end 
end

Below is the simple example for test cases using RSpec. Modify as per your requirements.

staff_controller.rb

def show
 @staff = Staff.find(params[:id])
end

RSpec

let(:staff) { FactoryBot.create(:staff) }


describe "GET #show" do
  it "Renders show page for valid staff" do
    get :show, {:id => staff.to_param}
    expect(response).to render_template :show
  end
  it "redirects to root path on staff record not_found" do
    get :show, id: 100
    expect(response).to redirect_to(root_path)
  end
end
  • Related