On Dec 6, 2009, at 1:03 PM, Scott Olmsted wrote:

> So am I right in thinking that a cart should not be tied to a user?  
> Or at least the logic in get_cart should be reversed: look first for  
> a cart pointed to by the session, then look for one belonging to the  
> user?

I'd say it depends on the intended life cycles of sessions vs carts,  
and both can be necessary. However there is a simpler alternative to  
consider. I'm going to go through a long road of scenarios to help you  
see why it works out, or you can skip to the very last paragraph, and  
I'll have written all that for nothing, but oh, well.

The key decisions to be made here are about the life cycle of the  
cart. Map out the various visitor patterns, and decide exactly what  
should happen to the cart.

Setup: how long does a session last in your application? Let's assume  
it is roughly 24 hours, and there's a session sweeper to delete (flag  
as inactive, whatever) stale sessions from the table as the mechanism  
for expiring sessions (whether by before_filter or cron).

(A) a visitor enters the site, a session is started, items are added  
to the cart. The visitor leaves the site, comes back after a short  
period (let's say 4 hours). The visitor's cookie is still available,  
so the session is still active. The session has the cart_id, so the  
cart is still available too. To do this requires nothing more that  
storing the card_id in the session. There's no @user involved.

(B) a visitor enters the site, a session is started, the cart_id is  
added to the session, items are added to the cart. The visitor leaves  
the site, doesn't come back for some extended period (let's say 30  
hours). Meanwhile, a session sweeper has deleted "stale" sessions  
included our visitor's. He comes back to the site, there is no session  
record, and so the connection to the cart_id is lost. From the user  
perspective, there is no cart. To do this requires nothing more that  
storing the card_id in the session. There's no @user involved.

(C) a visitor enters the site, a session is started, the cart_id is  
added to the session, items are added to the cart. Now the visitor  
logs in and becomes a @user. The user leaves the site, comes back  
after a short period (let's say 4 hours). The visitor's cookie is  
still available, so the session is still active. The session has the  
cart_id, so the cart is still available too. To do this requires  
nothing more that storing the card_id in the session. Even though we  
have a logged in @user, it had no bearing on the cart sesion/cart  
handling.

(D) a visitor enters the site, a session is started, the cart_id is  
added to the session, items are added to the cart. Now the visitor  
logs in and becomes a @user. The user leaves the site, comes back  
after a long period (let's say 30 hours). Meanwhile, a session sweeper  
has deleted "stale" sessions included our @user's. He comes back to  
the site, there is no session record, and so the connection to the  
cart_id is lost. From the user perspective, there is no cart. To do  
this requires nothing more that storing the card_id in the session.  
Even though we have a logged in @user, it had no bearing on the cart  
session/cart handling.

OK, so the first three cases are pretty typical, and there's really  
nothing to do except put cart_id in the session, and have a typical  
session sweeper of some kind.

But, let's look at (D) and say that we WANT the cart to still be  
available even after the session has been expired/deleted. If I  
actually log into a site and have a cart, I'd kind of like for that  
cart to hand around for at least some extended time period (7 days, 30  
days, something). So, let's step through it again...

(E) a visitor enters the site, a session is started, the cart_id is  
added to the session, items are added to the cart. Now the visitor  
logs in and becomes a @user. Let's add the cart_id to the @user object  
and save the @user. The user leaves the site and comes back 4 hours  
later. The session is still valid, it still has the cart_id, it is the  
same cart_id stored in user record, and the session still has the  
@user id as well (indicating an active login). Since there's an active  
login, and an active session, we can assume the cart_id id still  
valid. We have no other code as of yet that would have changed the  
cart_id in the user record, so at this point IMO you just do nothing  
because there's nothing that would have invalidated that cart_id.

(F) a visitor enters the site, a session is started, the cart_id is  
added to the session, items are added to the cart. Now the visitor  
logs in and becomes a @user. Let's add the cart_id to the @user object  
and save the @user. The user leaves the site, comes back after a long  
period (let's say 30 hours). Meanwhile, a session sweeper has deleted  
"stale" sessions included our @user's. He comes back to the site,  
there is no session record, so he's no longer logged in and so the  
connection to the cart_id is lost. From the user perspective (and the  
Rails perspective), there is no cart right now. A new session is  
created. The user has a choice right now:
        - logs in and gets his previous cart restored (does he know he can do  
that?)
        - starts creating a new cart
                - logs in -- oh, oh, now what? Do we use the new cart? the old 
cart?  
merge the two?
                - since the user assumed the old cart was gone, IMO, you ignore 
the  
old cart and use the new one.

Another option -- Two separate cookies! Let the session system handle  
its own cookie like normal. *Don't* store the cart_id in the session.  
*Don't* store the cart_id in the user record. Instead, create a second  
independent cookie that is not tied to the expiration of the session.  
Store the cart_id in this new cart cookie. Use cookie expiration  
attributes to have that cookie last as long as you want (7 days, 30  
days, "forever"). Now, no matter when the user comes back, or whether  
the user was ever logged in or not, the old cart will still be  
available--as long as you match your cart sweeping to complement the  
expiration timing of the cookie.

-- greg willits


-- 
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby

Reply via email to