简体   繁体   中英

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?

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

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.

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 %>

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM