# Shopping cart with arbitrary promotions model

**URL:** <https://www.ruby-forum.com/t/shopping-cart-with-arbitrary-promotions-model/144956>\
**Category:** Rails\
**Created:** [August 4, 2008, 6:10pm UTC](https://www.ruby-forum.com/t/shopping-cart-with-arbitrary-promotions-model/144956 "2008-08-04T18:10:50Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![txco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/c0e974/32.png) [@txco](https://www.ruby-forum.com/u/txco)\
**Post date:** [August 4, 2008, 6:10pm UTC](https://www.ruby-forum.com/t/shopping-cart-with-arbitrary-promotions-model/144956/1 "2008-08-04T18:10:50Z")

</div>

Not exactly a rails question, but my cart is in rails :-p

I’m looking for a model which allows for promotions to make arbitrary  
changes to a users shopping cart / session — pretty much anything my  
account management wizards can dream up that they think might get more  
sales. For example, some standards would be: discounting the entire  
cart, discounting single items or a type of items, adding free items,  
giving free/discounted shipping, flagging a user so their next purchase  
applies for a different promotion, etc.

Please ignore my further prattling unless you’re interested.

I have a functioning cart that does this already, but it has problems  
which make introducing new types of promotions difficult. Namely, too  
much responsibility lies with the cart itself. My cart requires  
knowledge of the way the different types of promotions work, e.g. when  
calculating shipping costs it looks to promotions which affect shipping.  
When calculating discounts it looks to promotions that do discounts.  
When its state changes it looks to promotions that alter its contents,  
e.g. adding/removing bonus items if the promotion qualifies/fails to  
qualify. This works, but it means a few things:

1.) The cart has responsibility for applying/unapplying promotions.  
2.) Adding new promotion types means rewriting cart code to accommodate  
them, sometimes very convoluted code.

What I’d like is a model that somehow abstracts promotions away from the  
cart, but I can’t think of a good way to do it. Some kind of proxy  
might work perhaps, where a Promotion encapsulates the cart and proxies  
its methods, introducing its own code which alters the order. This gets  
messy though with multiple promotions. Currently my cart doesn’t  
require more than one promotion at a time, but i don’t want to write  
this code then have them come back next month with “Oh yeah, we want to  
be able to attach both a promotion and a coupon to the order.”

Anyone seen any interesting cart implementations that deal with this  
sort of thing?
