I'm working on a E Commerce app and I can´t figure out how I can update the product stock quantity when the user adds product to the cart. I followed a tutorial for most of this app since I'm a total newbie. But the tutorial doesn't go into how to update the product stock quantity when the user adds product to the cart.
so far I've added this method to the cart.rb
model
def upd_quantity
if cart.purchased_at
product.decrement!(quantity: params[:stock_quantity])
end
end
But I´m really stuck and don't know what I'm doing It would be great if someone could take a look at this and advise me how to implement this function to the app.
here is a link to the github repo https://github.com/DadiHall/brainstore
this what I have at the moment.
cart_item.rb
model
class CartItem
attr_reader :product_id, :quantity
def initialize product_id, quantity = 1
@product_id = product_id
@quantity = quantity
end
def increment
@quantity = @quantity + 1
end
def product
Product.find product_id
end
def total_price
product.price * quantity
end
def upd_quantity
if cart.purchased_at
product.decrement!(quantity: params[:stock_quantity])
end
end
end
cart.rb
model
class Cart
attr_reader :items
def self.build_from_hash hash
items = if hash ["cart"] then
hash["cart"] ["items"].map do |item_data|
CartItem.new item_data["product_id"], item_data["quantity"]
end
else
[]
end
new items
end
def initialize items = []
@items = items
end
def add_item product_id
item = @items.find { |item| item.product_id == product_id }
if item
item.increment
else
@items << CartItem.new(product_id)
end
end
def empty?
@items.empty?
end
def count
@items.length
end
def serialize
items = @items.map do |item|
{
"product_id" => item.product_id,
"quantity" => item.quantity
}
end
{
"items" => items
}
end
def total_price
@items.inject(0) { |sum, item| sum + item.total_price }
end
end
product.rb
model
class Product < ActiveRecord::Base
mount_uploader :image, ImageUploader
validates_presence_of :name, :price, :stock_quantity
validates_numericality_of :price, :stock_quantity
belongs_to :designer
belongs_to :category
belongs_to :page
def self.search(query)
where("name LIKE ? OR description LIKE ?", "%#{query}%", "%#{query}%")
end
end
`cart_controller.rb`
class CartsController < ApplicationController
before_filter :initialize_cart
def add
@cart.add_item params[:id]
session["cart"] = @cart.serialize
product = Product.find params[:id]
redirect_to :back, notice: "Added #{product.name} to cart."
end
def show
end
def checkout
@order_form = OrderForm.new user: User.new
@client_token = Braintree::ClientToken.generate
end
def remove
cart = session['cart']
item = cart['items'].find { |item| item['product_id'] == params[:id] }
if item
cart['items'].delete item
end
redirect_to cart_path
end
end
Does adding this line:
product.update_columns(stock_quantity: product.stock_quantity - 1)
To your add action in the CartsController do the trick?
def add
@cart.add_item params[:id]
session["cart"] = @cart.serialize
product = Product.find params[:id]
product.update_columns(stock_quantity: product.quantity - 1)
redirect_to :back, notice: "Added #{product.name} to cart."
end
Try this for removing the product from cart:
def remove
cart = session['cart']
item = cart['items'].find { |item| item['product_id'] == params[:id] }
product = Product.find(item['product_id'])
product.update_columns(stock_quantity: product.stock_quantity + 1)
if item
cart['items'].delete item
end
redirect_to cart_path
end
Note, this will only work if you are adding and removing 1 item/product at a time. I suggest renaming 'item' to 'product' in your remove action for consistency.