【问题标题】:Problems with Active Record Rails 4Active Record Rails 4 的问题
【发布时间】:2016-07-22 10:17:03
【问题描述】:

我正在尝试在 OrdersController#new 操作中调用一些 ActiveRecord 方法。 我已经在 Rails Console 中测试了代码,它按我的预期工作。 但是在控制器动作中它不会产生相同的

  order has_many cart_items
  cart has_many cart_items 
  cart_items belong_to order cart_items
  belong_to cart 
  cart_items belong_to product
  product has_many cart_items

def new
  @order.new
  @order.cart_items = current_cart.cart_items
  @order.save

  current_cart.cart_items.destroy_all
end

现在 current_cart 是一个 application_controller 方法,用于检查当前用户是否有购物车。如果是,它会从数据库中拉出该购物车,如果用户没有,那么它会为用户创建一个新的购物车。我在这里要做的是当用户完成他们的订单时,我试图将 cart_items 从 current_cart 转移到订单,然后清除购物车。

当我在 Rails 控制台中执行此操作时,它给了我想要的东西。使用 current_cart 中的 cart_items 订购,在我在购物车上运行 destroy_all 后,我有一个空的活动记录关联数组。

当我在我的控制器中测试这个时,Order 和 Cart 返回一个空的活动关联数组。

这是怎么回事?

    #application controller method of finding current_users cart
    def current_cart
    # if user is logged in
    if current_user
      @user = current_user
      # checking user to see if account is confirmed and verified
      if @user.confirmed_at != nil

        # checking if user already has cart in cart database
        if Cart.find_by(users_id: @user.id) != nil
          # find a row in the database where users_id: equal to @user.id
          # where clause does not work here
          cart = Cart.find_by(users_id: @user.id)
          session[:cart_id] = cart.id
          cart.save
          #establish Cart session cart for user
          Cart.find(session[:cart_id])
        else
          # create a new Cart Object for user.assign current_user's id to cart object
          cart = Cart.new
          cart.users_id = @user.id
          # save it to get cart id assign session[:cart_id] == cart.id
          cart.save
          session[:cart_id] = cart.id
        end
      end
    end
  end



class CartItemsController < ApplicationController
  before_action :set_cart_item, only: [:show, :edit, :update, :destroy]
# scope for most_recent and subtotal
# find out if rails sorts on update column cuz this is annoying.


  def create
    # grabbing cart from application controller current_cart method
    @cart = current_cart
    # session[:cart_id] = @cart.id
    # individual product items get added to cart item and added to cart and saved
    @cart_item = @cart.cart_items.build(cart_item_params)
    @cart.save
  end

  def update
    @cart = current_cart
    # finding cart_items by cart_id
    @cart_item = @cart.cart_items.find(params[:id])
    # @cart_items.order(:id)
    @cart_item.update_attributes(cart_item_params)
    @cart_items = @cart.cart_items.order(:id)
    # redirect 'cart_show_path'
    @cart.save
  end

  def destroy
    @cart = current_cart
    @cart_item = @cart.cart_items.find(params[:id])
    @cart_item.destroy
    @cart_items = @cart.cart_items
    @cart.save
  end

  private
    def set_cart_item
      @cart_item = CartItem.find(params[:id])
    end

    def cart_item_params
      params.require(:cart_item).permit(:cart_id, :product_id, :unit_price, :quantity, :total_price)
    end
end

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    当您说要从 current_cart 传输 cart_items 时,您是在传递对象,您并没有创建新的 cart_items(这意味着数据库 ID 相同),而当您执行 current_cart.cart_items.destroy_all 时,它是从数据库中删除它们。见ActiveRecord::Relation#destroy_all

    对于你的用例,只要你这样做就足够了

    def new
      @order.new
      @order.cart_items = current_cart.cart_items
      @order.save
    
      current_cart.cart_items = []
    end
    

    【讨论】:

    • 毗湿奴这行不通。当我进入 Rails 控制台时。我仍然得到 Order 和 Cart 的空数组。
    • 您确定@order.save 成功了吗?可能存在一些验证错误?试试@order.save!,如果验证失败会报错。如果您能向我们展示您是如何初始化current_cart 及其cart_items,那将会更有帮助
    • 是的,我确定@order.save 是成功的。因为我使用 Order.destroy_all 和 CartItems.destroy_all 清除了数据库中的记录,所以运行该操作并在 Rails 控制台中生成新的订单记录/对象。我试过保存!并且没有错误。我很快就会放一些调试代码。
    • 我试过迭代 current_cart.cart_items.each 做 |item| item.cart_id = nil 结束。我试过 current_cart.cart_items.destroy_all。我也试过 current_cart.cart_items = []。当我做最后两个时,它似乎清除了 order.cart_items 和 current_cart.cart_items 。设置 cart_id = nil 的第一个选项似乎适用于第一个订单。然后任何更多的订单都会将 cart_items 留在 current_cart 中。
    【解决方案2】:

    好吧,想通了。

    我使用的是@order.save,它没有处理错误消息!!!!!!!!! 在@order.save 之后!它给了我另一个模型中的验证错误。 我把它注释掉了,它起作用了。

    我迭代 current.cart_items 并将 cart_id 分配给 nil 并将 order_id 分配给 @order.id 本质上是清除购物车并将商品“转移”过来。

    但我想不出使用 destroy_all 的方法。我认为这不可能像@Sri 所说的那样。

    非常感谢!

    所以最后的代码是这样的:

    @order = Order.create!(users_id: current_cart.users_id)
    
    current_cart.cart_items.each do |item|
      item.order_id = @order.id
      item.save!
    end
    
    if @order.save
      current_cart.cart_items.each do |item|
      item.cart_id = nil
      item.save!
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      相关资源
      最近更新 更多