If you haven't seen The 15 minute E-Commerce Site CLICK HERE
I'm currently looking for Contract jobs, Contact Me if you are interested. Dave.
I've seen many shopping carts. Most work well enough. Some have glaring flaws. Lets start by identifying what makes a shopping cart great.
The first thing that comes to mind of a great cart is that it is "stupid". Sure that might sound crazy but it is very true. A shopping cart should not know much about your "order" or your "products". Your cart should simply be a bucket to keep a bunch of products for a specific user. It doesn't know the price of the products or anything about the checkout process.
The second thing about a great cart is that it ironically it is "smart" about itself. Your cart should not know about the order or products but it should know about itself. Note your cart is the combination of a "cart model" and "cart_items model". This cart_items model should have at a minimum the following fields:
Additionally the cart should only have the following field:
- user_id (allow NULL)
There are a couple interesting things I've left out of the minimum model. First is quantity. I would argue that quantity should be in your cart_items model. However removing quantity and just adding more cart_item records in your database is an alternative (Although I don't recommend this approach).
Additionally user_id is not a required field for the cart. Which means your minimum cart record in the database can just have an ID field and nothing else. Yes your cart does also have_many cart_items. This structure allows customers that are not yet logged in to have a shopping cart and only assign the user_id during the checkout process.
Also note I am in favor of adding user_id to the cart_items table to keep queries more simple.
One feature I added to the minimum model is the field item_type_id. item_type_id refers to a model that just has a name field. The ItemTypes are as follows:
What this simple field in the DB does is allows you to have a wish list and save for later functionality out of the box. Additionally you can WOW your marketing team by telling them all the items a user has ever deleted out of their cart or purchased. If you ever need to create a recommendation engine your cart will give you all the data you need.
Now with this model, purchasing an item is simply taking the items that are in the cart and have a item_type of shopping_cart and moving them to an order / order_items object. I won't go into detail but basically once you purchase an order_item you change the cart_item.item_type to "purchased".
Now you have an extremely slim cart with a tremendous amount of functionality.
Combining the Cart and Order Objects
I've heard the argument that using an order object for the cart "make things easier". Not only do I disagree but sorry, "You would be wrong". By mixing the cart and the order you have not separated concerns. This can make validations very conditional. It also mixes cart logic with order logic.
I view your cart as something that can be removed off the face of the planet and not effect much. Sure people would be upset to add things back to their cart but at the end of the day it would not effect anything financially. The order however is sacred. If an order was deleted you could lose financial data and even fulfillment information. Hence you don't want to be messing around with the order because you could be shooting yourself in the foot.
By nature your cart has a lot of abandoned records. If the order and cart are separated you could very easily archive the carts without much worry. If your order is your cart the risk to do this would be too great. One small bug could cost you way too much.