Headache with sessions being shared.

I have a really horrendous problem with sessions.

before_filter :find_cart_from_session

private def find_cart_from_session     if session[:cart] # if there's is a cart in the session       begin         @cart = Cart.find(session[:cart]) # return existing or new cart       rescue ActiveRecord::RecordNotFound         @cart = Cart.create         @cart.save         session[:cart] = @cart.id # add a new one       end     else       @cart = Cart.create       @cart.save       session[:cart] = @cart.id # add a new one     end     @cart end

This code works. I mean it will return the cart object but ...

2 different computers add the same product to their cart whoever gets the product in first get both products.

user 1 adds product 1 user 1 sees 1 product in their cart

user 2 adds product 1 user 2 sees no products user 1 refreshes and now sees two product 1's in their cart.

user 2 adds product 2 user 2 should now have 1 x product 1 and 1 x product 2 But user 2 has 0 x product 1 and 1 x product 2

user 1 now adds product 2 to their cart user 2 refreshes and has 2 x product 2

Now at this point both user 1 and user 2 should have 1 of each prioduct in their cart. Controller action for this is

  def add_to_cart     product = Product.find(params[:id])     @cart = find_cart     @cart.add_product(product)     redirect_to_category_menu   rescue ActiveRecord::RecordNotFound     logger.error("Attempt to access invalid product #{params[:id]}" )     redirect_to_category_menu 'Invalid product'   end

I'm using database storage for the session. This is a total nightmare and I have just lost all my confidence in Rails even though this may be something wrong with the way I have set up the environment this surely should not be allowed to happen. Any ideas on what I have got wron or should be looking at?

Thanks

James

First thing I'd do is run in development mode and double check what sql statements are being sent to the database to find those sessions. I've been working only with cookie sessions, so naturally I'd suspect that.

Then place a debugger statements here:

def find_cart_from_session     debugger     if session[:cart] # if there's is a cart in the session

and take a look at session[:cart]. Is it a blank string, what class is it, etc.

JDevine - Thank you for the pointers.

I've tracked down the problem.

This app was upgraded from Rails 2.1.2 to 2.3.2

The session handling changed between these versions and the :secret was moved to the config/initializers/session_store.rb

This obviously does not exist so I have created one which leads me on to another question Is there any way of setting the :key dynamically?

:key => some_function

def some_function   get_the_name_of_the_app_somehow? end

This would enable me to keep the keys unique for each application deployment.

James

JDevine wrote:

Honestly I don't have experience with that, or even know exactly what the key does, but I suspect that you would want the key to remain the same for the life of the app, so you really don't want to set it dynamically. Otherwise, every time you make a change to the app your sessions would all be invalid, which causes nasty errors that are hard to decipher. Set the key by hand or via a generator or something when you create the app then leave it alone.

That works for one site but with multiple sites each key should be unique so I need it to be set dynamically otherwise people visiting site one will have the same key for site 2, site 3 and so on...

But I'm still struggling with the session issue so I'll worry about the key later.

JDevine wrote:

ActiveSupport::SecureRandom.hex(64) can generate session key