Help with session

oookk, so i have 2 actions , create and destroy, i can get session[:cart_id] from inside the create method but not from inside the delete method.

def create     @cart = current_cart     Rails.logger.debug "SESSION INFO HERE #{session[:cart_id]}" this here is 18

. . .

def destroy     # @cart = current_cart     @line_item = LineItem.find(params[:id])     Rails.logger.debug "SESSION INFO HERE #{session[:cart_id]}" this here is nil

. . .

here is how i create the cart

private   def current_cart     begin       Cart.find(session[:cart_id])     rescue ActiveRecord::RecordNotFound       Rails.logger.debug "SESSION IS #{session.inspect}" <== is empty when i call it from the destroy method      cart = Cart.create      session[:cart_id] = cart.id      cart     end   end

anyone knows whats going on?

does it work when you uncomment this line in destroy?

# @cart = current_cart

oh wait.. ignore that. of course it will work but it just creates a new cart. :-\ sorry, long day

If i do that what happens is that since the session is nil a new cart i created and i lose all the items in the original “current_cart”

and a new cart is rendered with no items.

even if i successfully delete the right line_item, when the cart is update is populated from the new current_cart and everything is lost.

By the way im doing everything via ajax.

but why does the session changes? or why cant i access it form the destroy method?

any before filters clearing it out?

with AJAX, if your rails app is on a different domain than the page hosting the form the cookies may get blocked resulting in no session information being available.

Do a global search through your app and make sure you are not accessing the session anywhere else. If there are any other references but you believe that you are not accessing them then put ruby-debug breakpoints at each and make sure you do not get there.

Colin

When the create action gets called is there also another ajax action that gets triggered by the browser at roughly the same time? There can be race conditions when that sort of things happens.

Fred

no other ajax call is made

It works well without ajax, there seem to be a problem when calling the action via ajax

i official , if i try to do and ajax request to the destroy action i cant access the session, can some on please test to see if its a bug?

in debuggin, if i stop to check the session during the destroy action i get this

“DEPRECATION WARNING: Disabling sessions for a single controller has been deprecated. Sessions are now lazy loaded. So if you don’t access them, consider them off. You can still modify the session cookie options with request.session_options. (called from block in at_line at (eval):5)”

as if am using

session :off

but am not, could this be related to devise?

it seems to be realted to my rails.js file i think is not passing the csrf_token on every request

ok , i just confirmed this. here is the problem

my rails.js file i installed with jquery rails, is not properlly passing the csrf token so

“The request will also not include the required CSRF data, and as of Rails 3.0.4 the session is silently reset instead of throwing an ActionController::InvalidAuthenticityToken error. This is why you suspect the authentication issue lies with Devise, but it is actually being triggered within Rails itself.”

that is why i cant see the session from the destroy action, when i remove

protect_from_forgery

from the application_controller everything works ok , it also works if the request is not ajax based with protect_from_forgery enable.

Ok is fixed by downloading the latest rais.js that supports rails 3.0.4

it has this new method in it which makes sure the csrf token is sent on every request

// Make sure that every Ajax request sends the CSRF token

function CSRFProtection(xhr) {

	var token = $('meta[name="csrf-token"]').attr('content');

	if (token) xhr.setRequestHeader('X-CSRF-Token', token);

}

if ('ajaxPrefilter' in $) $.ajaxPrefilter(function(options, originalOptions, xhr){ CSRFProtection(xhr) });

else $(document).ajaxSend(function(e, xhr){ CSRFProtection(xhr) });