You know what--after some coding and pondering, this is just not working. Creating an empty cart after each purchase just feels wrong, even if just for signed-in users, and there's too much logic here, the shopping cart ought to be simpler.
Seems to me like carts go with sessions. Lose your session, lose your cart. Take the order_id out of the cart table and put a cart_id into the order table so it can be retrieved later if necessary. After a purchase or a click on 'Empty Cart', set @cart = nil rather than adding one more empty cart to the database (and let the cart page display "Your cart is empty" based on the nil, rather than creating an empty cart). Keep all carts, used for purchases or abandoned. So much simpler. Wikipedia (not exactly the greatest authority, but eh..) says In <http://en.wikipedia.org/wiki/Computing>computing, a cookie (also tracking cookie, browser cookie, and HTTP cookie) is a small piece of text stored on a user's computer by a <http://en.wikipedia.org/wiki/Web_browser>web browser. A cookie consists of one or more <http://en.wikipedia.org/wiki/Attribute-value_pair>name-value pairs containing bits of information such as user preferences, <http://en.wikipedia.org/wiki/Shopping_cart_software>shopping cart contents, the identifier for a server-based <http://en.wikipedia.org/wiki/Http_session>session, or other data used by <http://en.wikipedia.org/wiki/Website>websites. A paper referenced there (http://papers.ssrn.com/sol3/papers.cfm?abstract_id=597543) has some history: Netscape developed cookies precisely for creating shopping carts (page 298). Good enough for me. Another possible advantage: the session can be set to expire. I just discovered that with every request a before_filter is deleting all carts older than a week, all orders older than a day, and all payment information not used with 30 minutes, three database accesses. More things that should go into cron jobs. Scott At 04:45 PM 12/6/2009, you wrote: >Yes, agreed, who the cart belongs to should not be discarded by >doing '@cart.user_id = nil'. And fetching the latest cart of >possibly many solves some problems. > >So when a signed-in user purchases or clicks 'Empty cart', a new, >empty cart would be created belonging to them. If they purchase >nothing more, an empty cart remains in the database. There are not >many users, so that's not a problem. > >The cart of a purchaser not signed in would be tied to the order >record, as with all orders. The session would be cleared of the cart >id. A new cart would be created when they next click on 'Add Item To >Cart' or 'View Cart'. That works. > >For someone not signed in who clicks 'Empty cart', the cart would >not be cleared of items (violating the rule), rather, a new cart >would be created and its id put into the session. This will leave >behind some empty, abandoned carts. C'est la vie. > >Thanks much, that's very helpful. > >Scott > > >At 03:55 PM 12/6/2009, you wrote: >>Scott Olmsted wrote: >> > >> > There's no 'Save For Later', and there's no 'Empty Cart' or >> 'Discard Cart'. >> > >> > While carts are never removed from the database, they are discarded >> > after the gateway reports acceptance of the payment: >> > >> > @cart.user_id = nil >> > @cart.save >> >>That breaks the rule "thou shalt not delete, overwrite, or destroy data". >> >>Ideally, a database - especially e-commerce related - should only add new >>records. "Destroy" a cart by adding another one, and then the user only ever >>sees the cart with the highest timestamp. Rails's model observers and named >>scopes should make these features trivial to add. Should. >> >>Also, it might be time for the "got unit tests" question. RoR makes >>them sooo >>tragically easy... >> >>-- >> Phlip >> http://c2.com/cgi/wiki?MoreliaViridis >> >>-- >>SD Ruby mailing list >>[email protected] >>http://groups.google.com/group/sdruby > >-- >SD Ruby mailing list >[email protected] ><http://groups.google.com/group/sdruby>http://groups.google.com/group/sdruby -- SD Ruby mailing list [email protected] http://groups.google.com/group/sdruby
