In a rails 5 e-commerce site, Carts from a classic shopping cart model have not been destroyed because of a badly written code, so now the heroku database has more than 10 000 rows of empty carts. If I destroy them from the heroku console, next time a user who already came to the site but gave up in the middle of the buying process will try to reach the site, he will get a 404 error like this:
ActiveRecord::RecordNotFound (Couldn't find Cart with 'id'=305)
Because of the cookies, obviously. The heroku DB has exceeded its allocated storage capacity, so I need to destroy the empty carts. (And fix the code, but this is not the question here). Is there a way to do this smoothly?
class CartsController < ApplicationController
def show
@cart = @current_cart
total = []
@cart.order_items.each do |item|
total << item.product.price_cents * item.quantity.to_i
end
@cart.amount_cents_cents = total.sum
end
def destroy
@cart = @current_cart
@cart.destroy
session[:cart_id] = nil
redirect_to root_path
end
end
class OrdersController < ApplicationController
before_action :authenticate_user!
def create
@order = Order.new
total = []
@current_cart.order_items.each do |item|
total << item.product.price_cents * item.quantity.to_i
end
@order.amount_cents_cents = total.sum
if @order.amount_cents_cents == 0
redirect_to root_path
else
@current_cart.order_items.each do |item|
@order.order_items << item
item.cart_id = nil
end
@user = current_user
@order.user_id = @user.id
@order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
redirect_to order_path(@order)
end
end
class ApplicationController < ActionController::Base
before_action :current_cart
def current_cart
if session[:cart_id]
cart = Cart.find(session[:cart_id])
if cart.present?
@current_cart = cart
else
session[:cart_id] = nil
end
end
if session[:cart_id] == nil
@current_cart = Cart.create
session[:cart_id] = @current_cart.id
end
end
instead of using find
which throws an exception if it does not find a record you can use find_by_id
which returns nil
. And if you get nil
you can make the cart empty and display a message to the user that your cart is empty.
also, you can use rescue block to rescue from the exception thrown by find