I’m writing a model instance method that should find an AR association if it exists, or create it if it doesn’t. How can I do this so that after the first find, the database isn’t queried again? I have two version of this method below but both have drawbacks.
This method performs the query every time which is inefficient.
def cart
carts.order('created_at desc').where(:purchased_at => nil).first || carts.create
end
This method only does the db lookup once, but gets out of sync after something like cart.destroy.
def cart
@cart_ || @cart_ = carts.order('created_at desc').where(:purchased_at => nil).first || @cart_ = carts.create
end
ActiveRecord Relations have a little-known feature that allows you to create an instance from them:
Combine that with
find_or_createand you’re on your way:Every time you call
cartRails will run a query, however it is very performant because it’ll hit the query cache which expires at the end of the request. Assuming you’re not clearing all carts in between calls to this method, you should be fine.