DaudiHell
DaudiHell

Reputation: 808

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.rbmodel

 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.rbmodel

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

Upvotes: 1

Views: 1965

Answers (1)

malexanders
malexanders

Reputation: 3343

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.

Upvotes: 1

Related Questions