ActiveRecord # существует? или спасение от ActiveRecord:: RecordNotFound
Каков рекомендуемый способ решения следующих ситуаций:
Предположим, что у меня есть модель под названием Cart
, которая имеет отношение 1-1 с моделью Person
и тот же PK (идентификатор пользователя).
В методе index
моего cart_controller
я хочу проверить, существует ли Cart
для текущего пользователя.
Если я делаю Cart.find(the_user_id)
, и корзина не существует, возникает исключение RecordNotFound
.
Я вижу два способа решения этого вопроса:
1. спасение от исключения
begin
@cart = Cart.find(the_user_id)
#more code here
rescue ActiveRecord::RecordNotFound
#the cart is empty message
end
2. использовать ActiveRecord # существует? Метод
if Cart.exists?(the_user_id)
@cart = Cart.find(the_user_id)
#more code here
else
#the cart is empty message
end
Из моих (ограниченных) знаний об обработке exeption я знаю, что не рекомендуется использовать исключения таким образом, но делает дополнительный запрос каждый раз, когда он стоит?
Ответы
Ответ 1
Вы можете попробовать спросить объект пользователя для своей корзины. Скажем, у вас есть пользователь, назначенный на @user
, тогда, если у пользователя есть тележка, он будет @user.cart
. Если @user.cart
- nil
, то у них их нет.
Это предполагает, что вы правильно установили отношения между настройками.
Ответ 2
Используйте find_by_id вместо find:
@cart = Cart.find_by_id(params[:id])
nil, если он не существует, поэтому вы можете проверить "if @cart" в своем контроллере/просмотре по мере необходимости
Ответ 3
Почему бы вам не сделать что-то вроде...
@cart = @user.cart || @user.cart.new
Не беспокоиться об исключениях или операторах if/else.
Тогда, на ваш взгляд, у вас может быть что-то вроде...
<% 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 %>
Ответ 4
существует? приведет к еще одному оператору SQL, если ребята из ActiveRecord не оптимизируют это (я бы не рассчитывал на это).
Поэтому я бы посоветовал использовать исключение, это намного дешевле, чем SQL-запрос.