Last active
December 29, 2015 10:59
-
-
Save arches/7660643 to your computer and use it in GitHub Desktop.
hash-backed shopping cart w session default
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'active_support/hash_with_indifferent_access' | |
class Cart | |
include Enumerable | |
attr_writer :storage | |
def each(&blk) | |
deal_ids.each(&blk) | |
end | |
def add(deal_id, options={}) | |
deal_hash[deal_id.to_i] = HashWithIndifferentAccess.new(options) | |
remove(deal_id) if options_for(deal_id.to_i)[:quantity] == 0 | |
store | |
end | |
def remove(deal_id) | |
deal_hash.delete(deal_id.to_i) | |
store | |
end | |
def deal_ids | |
deal_hash.keys | |
end | |
def total | |
Deal.find(deal_ids).inject(0) { |sum, deal| sum + (deal.price * options_for(deal.id).fetch(:quantity){1}) } | |
end | |
def options_for(deal_id) | |
deal_hash[deal_id] | |
end | |
def empty? | |
deal_ids.length == 0 | |
end | |
def clear! | |
deal_ids.collect{|id| remove(id)} | |
end | |
def size | |
deal_ids.length | |
end | |
private | |
def deal_hash | |
@deal_hash ||= storage[:cart] | |
@deal_hash ||= {} | |
end | |
def store | |
storage[:cart] = deal_hash | |
end | |
def storage | |
@storage ||= {} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The magic happens in the @storage variable. By default, it's just a hash. So I can do something like this out of the box:
But I can use any hash I want, doesn't have to be a new hash. What else is a hash? The session!
It's just dependency-injection, but the fact that hashes have such small interfaces make it easy to swap out other things. For example, memcache:
Or write an adapter!
So now we have file-system persisted carts