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 Answer
Reset to default 3class 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
update!
instead ofupdate
in the Approach #1. Does it work? – mechnicov Commented Mar 10 at 23:14Cart
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 online_items
and a get rid of a lot of complexity. – max Commented Mar 11 at 7:04