andi
andi

Reputation: 14458

ActiveRecord#exists? or rescue from ActiveRecord::RecordNotFound

What is the recommended way of handling the following type of situations:

Supposing I have a model called Cart, that has a 1-1 relationship with the model Person and the same PK (the user's id).

In the index method of my cart_controller I want to check if a Cart exists for the current user. If I do Cart.find(the_user_id) and a cart doesn't exists a RecordNotFound exception gets raised.
I see two ways of solving this:

1. rescue from the exception

 begin
    @cart = Cart.find(the_user_id)
    #more code here
 rescue ActiveRecord::RecordNotFound
    #the cart is empty message
 end

2. use ActiveRecord#exists? method

 if Cart.exists?(the_user_id)
    @cart = Cart.find(the_user_id)
    #more code here
 else
    #the cart is empty message
 end

From my (limited) knowledge on exeption handling I know that it's not recommended to use exceptions this way, but is making an extra query every time worth it?

Upvotes: 17

Views: 18397

Answers (4)

Lee Irving
Lee Irving

Reputation: 543

You could try asking the user object for its cart. Let's say you have the user assigned to @user then if the user has a cart it would be @user.cart. If @user.cart is nil then they don't have one.

This assumes that you have the relationships between the models set up correctly.

Upvotes: 23

danengle
danengle

Reputation: 566

Why don't you do something like...

@cart = @user.cart || @user.cart.new

No worrying about exceptions or if/else statements. Then in your view you could have something like...

<% if @cart.empty? # or whatever method you use to determine 
     # if there is nothing in the cart...maybe .blank? is fine? 
%>
    <p>Your cart is empty</p>
<% else %>
    <!-- loop through objects in your cart -->
<% end %>

Upvotes: 3

Oinak
Oinak

Reputation: 1805

Use find_by_id instead of find:

@cart = Cart.find_by_id(params[:id])

nil's if it does not exist so you can check "if @cart" in your controller/view as needed

Upvotes: 34

alamar
alamar

Reputation: 19343

exists? would result in one more SQL statement, unless ActiveRecord guys optimized this out (I wouldn't count on that).

So I'd advise to use an exception, it's much cheaper than a SQL statement.

Upvotes: 0

Related Questions