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