Daði Hall Daði Hall - 4 months ago 91
Ruby Question

Updating in stock quantity based on shopping cart quantity in rails app?

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

Answer

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] }

      item = item.update_columns(stock_quantity: item.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.

Comments