Module: ActiveCart::Acts::Cart::ClassMethods

Defined in:
lib/active_cart/acts_as_cart.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) acts_as_cart(options = {})

acts_as_cart - Turns an ActiveRecord model in to a cart. It can take a hash of options

state_column: The database column that stores the persistent state machine state. Default: state
invoice_id_column: The column that stores the invoice id. Default: invoice_id
cart_items: The model that represents the items for this cart. Is associated as a has_many. Default: cart_items
order_totals: The model that represents order totals for this cart. It is associated as a has_many. Default: order_totals

Example

class Cart < ActiveModel::Base
  acts_as_cart
end

The only two columns that are required for a cart model are the state_column and invoice_id_column

You can create custom acts_as_state_machine (aasm) states and events after declaring acts_as_cart

NOTE: this is a STORAGE ENGINE, so you need to create it (by finding by id) then pass the result in to ActiveCart::Cart.new. It might look something like this (Most likely in ApplicationController):

if session[:cart_id]
  engine = Cart.find(session[:cart_id])
  @cart = ActiveCart::Cart.new(engine) if engine
end


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/active_cart/acts_as_cart.rb', line 39

def acts_as_cart(options = {})
  cattr_accessor :aac_config
  
  self.aac_config = {
    :state_column => :state,
    :invoice_id_column => :invoice_id,
    :cart_items => :cart_items,
    :order_totals => :order_totals
  }

  self.aac_config.merge!(options)

  class_eval do
    #include AASM::Persistence::ActiveRecordPersistence
    include ActiveCart::CartStorage

    #:nodoc
    def invoice_id
      read_attribute(self.aac_config[:invoice_id_column])
    end
    
    #:nodoc
    def state
      read_attribute(self.aac_config[:state_column])
    end

    #:nodoc
    def find_cart_item(item, options = {})
      self.send(:cart_items).find(:first, :conditions => [ 'original_id = ? AND original_type = ?', item.id, item.class.to_s ])
    end

    #:nodoc
    def add_to_cart(item, quantity = 1, options = {})
      cart_item = find_cart_item(item, options)
      if cart_item
        cart_item.quantity += quantity
        cart_item.save!
      else
        cart_item = self.send(:cart_items).create!(self.aac_config[:cart_items].to_s.classify.constantize.new_from_item(item, { :quantity => quantity }.merge(options)).attributes.delete_if {|key, value| value == nil})
      end
      self.reload 
    end

    #:nodoc
    def remove_from_cart(item, quantity = 1, options = {})
      cart_item = find_cart_item(item, options)
      if cart_item
        quantity = cart_item.quantity if quantity == :all

        if cart_item.quantity - quantity > 0
          cart_item.quantity = cart_item.quantity - quantity
          cart_item.save!
        else
          cart_item.destroy
        end
      end
      self.reload 
    end

    #:nodoc
    def update_cart(item, quantity = 1, options = {})
      cart_item = find_cart_item(item, options)
      if cart_item
        diff = quantity - cart_item.quantity
        
        if diff < 0
          return remove_from_cart(item, -1 * diff, options)
        else
          return add_to_cart(item, diff, options)
        end
      else
        return add_to_cart(item, quantity, options)
      end
    end
  end
 
  aasm_column self.aac_config[:state_column]

  has_many self.aac_config[:cart_items], :dependent => :destroy
  has_many self.aac_config[:order_totals], :dependent => :destroy

  extend Forwardable
  def_delegators self.aac_config[:cart_items], :[], :<<, :[]=, :at, :clear, :collect, :map, :delete, :delete_at, :each, :each_index, :empty?, :eql?, :first, :include?, :index, :inject, :last, :length, :pop, :push, :shift, :size, :unshift
end