Rails 购物车 - 如何在没有用户获得 404 的情况下在生产中销毁它们?

Rails shopping Cart - how to destroy them in production without User to get a 404?

在一个rails5的电子商务网站中,由于代码写得不好,经典购物车模型中的购​​物车没有被破坏,所以现在heroku数据库有超过10000行空购物车.如果我从 heroku 控制台销毁它们,下次已经访问该站点但在购买过程中放弃的用户将尝试访问该站点,他将收到如下 404 错误:

ActiveRecord::RecordNotFound (Couldn't find Cart with 'id'=305)

显然是因为饼干。 heroku DB 已超出其分配的存储容量,因此我需要销毁空车。 (并修复代码,但这不是这里的问题)。 有什么办法可以顺利做到吗?

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

您可以使用 find_by_id which returns nil,而不是使用 find,它会在找不到记录时抛出异常。如果您得到 nil,您可以将购物车清空并向用户显示一条消息,表明您的购物车是空的。

此外,您可以使用 rescue 块从 find

抛出的异常中解救出来