Skip to content

Instantly share code, notes, and snippets.

@arieliten
Created March 19, 2013 14:22
Show Gist options
  • Save arieliten/5196497 to your computer and use it in GitHub Desktop.
Save arieliten/5196497 to your computer and use it in GitHub Desktop.
Basic Shopping Cart implementation, using ActiveRecord for persistence of Order/Item and a module to encapsulate the logic of a Cart
module MyApp
class Cart
attr_accessor :order, :items # <== ActiveRecord Instance of Order & Item
def initialize(user, token)
@order ||= user.blank? ? Order.load_for_guest(token) : Order.load_for_customer(user)
@items = @order.items
end
def add(product_id, quantity=1)
if @items.where(product_id: product_id).size.zero?
@items.create(product_id: product_id, quantity: quantity)
else
@items.where(product_id: product_id).first.increment(:quantity, quantity)
end
end
def add_multiple(params) # params = { [{quantity:<val>, product_id:<val>}, ...] }
params.each do |item|
add(item[:product_id], item[:quantity])
end
end
def remove(product)
@items.where(product: product).map(&:destroy)
end
def clean
@items.destroy_all
end
# ...
end
end
class CartsController < ApplicationController
before_filter :load_cart
# params = { items: [
# {quantity: 2, product_id: 613},
# {quantity: 1, product_id: 3271},
# {quantity: 4, product_id: 981}
# ]
# }
def update
@cart.add_multiple(params[:items])
end
private
def load_cart
@cart ||= MyApp::Cart.new(current_user, session[:cart_id])
session[:cart_id] ||= @cart.id
end
end
class Item < ActiveRecord::Base
belongs_to :product
after_initialize :set_defaults
def set_defaults
self[:quantity] ||= 1
end
end
class Order < ActiveRecord::Base
belongs_to :user
has_many :items
# .... State Machine conf ....
scope :pending, where(state: 'pending')
def self.load_for_customer(user)
self.pending.where(user: user).last.blank? ? self.create(user: user) : self.pending.where(user: user).last
end
def self.load_for_guest(cart_id)
if (cart_id.blank? || self.pending.find_by_id(cart_id).blank?)
self.create
else
self.pending.find_by_id(cart_id)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment