Я следую книге «Agile Web Development with Rails 4» и выполнил упражнение Playtime, создав кнопку уменьшения, чтобы уменьшить количество товара в виртуальной корзине покупок. Он должен быть удален, если его количество равно одному.Agile Web Development with Rails 4 - Итерация F - Действие по уменьшению -> повторное использование уничтожения
Хотя это непростая задача, я беспокоюсь о дублировании кода, потому что в моем контроллере есть действие destroy, которое удаляет элемент с помощью AJAX. Если я изменю это позже, я тоже не хочу менять его для декрементации. Кроме того, мне нужно скопировать весь AJAX, который я использую для удаления в decrmentation. Я хотел бы использовать этот метод со всеми его AJAX и т. Д., Чтобы обрабатывать случай, когда это последний элемент такого рода в корзине, чтобы удалить его.
Немного как это (псевдокод):
IF last_item_of_that_kind
execute destroy_action
ELSE
decrement
forward_to ...
END
ли кто-нибудь имеет представление о том, как хорошо достичь его просто «вперед», чтобы разрушающего действия в этом случае?
LineItemController:
# DELETE /line_items/1
# DELETE /line_items/1.json
def destroy
@cart = Cart.find(session[:cart_id])
@line_item.destroy
respond_to do |format|
format.html { redirect_to cart_url(@cart), notice: 'Line item was successfully destroyed.' }
format.js { @current_item = @line_item }
format.json { head :no_content }
end
end
# POST /line_items
# POST /line_items.json
def decrement
@cart = Cart.find(session[:cart_id])
@line_item = LineItem.find_by_id(params[:id])
# did it in the cart-model first, but that does not allow to redirect correctly
if @line_item.quantity > 1
@line_item.quantity -= 1
if @line_item.save
respond_to do |format|
format.html { redirect_to cart_url(@cart), notice: 'Line item was successfully decreased.' }
format.js { @current_item = @line_item }
format.json { head :ok }
end
end
else
# did not find a way to call the destroy-mehtod with post, to avoid code-duplicates
@line_item.destroy
respond_to do |format|
format.html { redirect_to cart_url(@cart), notice: 'Line item was successfully destroyed.' }
format.js { @current_item = @line_item }
format.json { head :ok }
end
end
end
Конечно, было бы лучше, чтобы справиться с самой декрементирования в корзину модели, но тогда я должен был бы проверить значения, тоже.
Это хорошая практика, чтобы назвать контроллер-методы в модели? Зачем мне нужно, чтобы save-method обходил проверку? Я не вижу случая для этого. Для методов создания необходимо, и в точке декрементации или удаления он должен быть действительным. Спасибо за Ваш ответ. – Klumbe
@Klumbe: '#decrement!' И '#destroy!' - оба метода модели, принадлежащие 'ActiveRecord :: Base', а не контроллер. Если ваш 'LineItem' имеет недопустимые данные (например.цена установлена на '' 100 "' для целочисленного поля вместо '100'), он всегда будет удаляться вместо декрементированного. – fylooi
О, хорошо, но если они принадлежат к модели, это не помогает мне с моей проблемой относительно повторного использования моего контроллера-метода (особенно перенаправления, AJAX и т. Д.), Хотя это полезная информация. Вы хотите сказать, что невозможно удалить недопустимый 'LineItem' без оператора bang? По-моему, оно будет удалено так или иначе (в любом случае «количество <= 1'). Поскольку элемент сохраняется, прежде чем я не вижу, почему валидация не сработает или как цена изменится на неправильный тип, если я не делаю этого явно (чего я не делаю). – Klumbe