1
votes

just a (hopefully) quick one today, apologies if it's super simple and I'm just thick.

I'm have a basic e-commerce app that I'm working on, and have 2 questions:

  1. I'd create a :product in admin with an amount of stock. I'm looking to automatically update the stock of a :product if one or more is added to someone's cart as a :cart_item, based on the quantity that they've got in their cart (even before checkout). So one update if a product is added, and another update if a customer changes quantity from the cart view.
  2. I'd like the name and price of :cart_item in a customers cart to be updated automatically if admin updates the associated :product.

Here are my model associations so far:

Customer
  has_one :cart
  has_many :orders

Product
  has_many :cart_items

Cart
  belongs_to:customer
  has_many :cart_items

CartItem
  belongs_to :product
  belongs_to :cart

I only have scaffolds so far so all my current code is out of the box Rails 3.2.14.

I'm just not sure how to get the :cart_items to interact with the :products and vice versa. What code/extra functionality should I add to get this working? Thanks for the help.

1
just a suggestion but keep in mind most shopping carts are abandoned. normally stock would not be adjusted until after the transaction has gone through.cartalot

1 Answers

0
votes

Assuming that CartItem belongs_to :product (which seems likely), and has a quantity attribute that indicates the number in the cart:

1) I believe the functionality you want could be accomplished using callbacks on CartItem. For instance,

class CartItem < AR:B
  after_save :remove_from_stock
  after_destroy :return_to_stock


  def remove_from_stock
    product.stock -= self.quantity
    product.save
  end

  def return_to_stock
    product.stock += self.quantity
    product.save
  end
end

2) When you display the CartItem, just refer to it's associated product:

<% @cart_items.each do |cart_item| %>
  Item Name: <%= cart_item.product.name %>
  Item Price: <%= cart_item.product.price %>
<% end %>

This way, any change to the associated Product will be reflected in any view that refers to it. If you're displaying many at once, make sure to use eager loading to avoid N+1 queries:

@cart_items = CartItem.includes(:product).where(<whatever>)