ruby on rails - Line items disappear when moving from cart to order - Stack Overflow

I'm working on a shopping cart system in Rails 7 where I'm trying to move line items from a c

I'm working on a shopping cart system in Rails 7 where I'm trying to move line items from a cart to an order during checkout. However, I'm running into a strange issue where the line items don't seem to be properly associated with the order after saving.

Here's my order controller:

def create
  @order = Order.new(order_params)
  @order.add_line_items(@cart)

  respond_to do |format|
    if @order.save
      @cart.destroy
      # Other code...
    end
  end
end

I've tried different approaches in my add_line_items method:

  • Approach 1 (doesn't work - order has 0 line items after save):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
        item.update(cart_id: nil)
      end
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    
  • Approach 2 (works properly):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
      end
      cart.line_items.update_all(cart_id: nil)
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    
  • Approach 3 (doesn't work - same issue as approach 1):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
        item.cart_id = nil
      end
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    

In all approaches, the puts statement shows that there are 2 line items in the order's collection at that moment. However:

  • With approaches 1 and 3, after @order.save is called, the order ends up with 0 line items.
  • With approach 2 (using update_all), everything works as expected.

I don't understand why setting cart_id = nil on each item individually would cause them to lose their association with the order, especially since the line_items.count shows them as being associated right after the loop.

My models:

class Cart < ApplicationRecord
  has_many :line_items, dependent: :destroy
end

class Order < ApplicationRecord
  has_many :line_items, dependent: :destroy
end

class LineItem < ApplicationRecord
  belongs_to :cart, optional: true
  belongs_to :order, optional: true
end

I'm working on a shopping cart system in Rails 7 where I'm trying to move line items from a cart to an order during checkout. However, I'm running into a strange issue where the line items don't seem to be properly associated with the order after saving.

Here's my order controller:

def create
  @order = Order.new(order_params)
  @order.add_line_items(@cart)

  respond_to do |format|
    if @order.save
      @cart.destroy
      # Other code...
    end
  end
end

I've tried different approaches in my add_line_items method:

  • Approach 1 (doesn't work - order has 0 line items after save):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
        item.update(cart_id: nil)
      end
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    
  • Approach 2 (works properly):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
      end
      cart.line_items.update_all(cart_id: nil)
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    
  • Approach 3 (doesn't work - same issue as approach 1):

    def add_line_items(cart)
      cart.line_items.each do |item|
        line_items << item
        item.cart_id = nil
      end
      puts "self-> #{self.line_items.count}" # This prints "2" as expected
    end
    

In all approaches, the puts statement shows that there are 2 line items in the order's collection at that moment. However:

  • With approaches 1 and 3, after @order.save is called, the order ends up with 0 line items.
  • With approach 2 (using update_all), everything works as expected.

I don't understand why setting cart_id = nil on each item individually would cause them to lose their association with the order, especially since the line_items.count shows them as being associated right after the loop.

My models:

class Cart < ApplicationRecord
  has_many :line_items, dependent: :destroy
end

class Order < ApplicationRecord
  has_many :line_items, dependent: :destroy
end

class LineItem < ApplicationRecord
  belongs_to :cart, optional: true
  belongs_to :order, optional: true
end
Share edited Mar 10 at 22:50 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 10 at 22:47 Tiago AntunesTiago Antunes 11 3
  • 1 What's about update! instead of update in the Approach #1. Does it work? – mechnicov Commented Mar 10 at 23:14
  • Why not just ditch the Cart model completely? It's a very awkward construct. Create an order as soon as the user adds the first line item. Add a status column to the Order model which lets you tell how far along the user has gotten in the checkout process. That way you don't have to copy over anything and you can ditch the wonky double nullable foreign key columns on line_items and a get rid of a lot of complexity. – max Commented Mar 11 at 7:04
  • @max Good idea, with the possible use of a state_machine for the Order. – Thomas Commented Mar 19 at 0:33
Add a comment  | 

1 Answer 1

Reset to default 3
class Cart < ApplicationRecord  
  has_many :line_items, dependent: :destroy
end

You've told Rails to destroy all the LineItems associated with the cart when the Cart is destroyed. If the Cart is destroyed while the LineItems are still associated with the Cart they will be destroyed.

Method 1 does item.update(cart_id: nil) but never saves the change, so the items are still associated with the cart. They get destroyed with the cart. It should use update!.

Method 3 does item.cart_id = nil and again does not save the change. It should call save!.

Method 2 does cart.line_items.update_all(cart_id: nil). update_all happens immediately.

You can reduce add_line_items to...

@order.line_items << @cart.line_items

@cart.line_items.update_all(cart_id: nil)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744820465a4595583.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信