0

In my controller action i initialize a session of array and inserting values. These values are coming from the client side through ajax, so the page is not refreshed while inserting these values to an array.But suprisingly every time it iniatialize a new session instead of inserting to the same defined session. Here is my code

controller

def receive_tags
  parser = Yajl::Parser.new
  @hash = parser.parse(request.body.read)
  log=Logger.new(STDOUT)
  log.error(@hash)
  session[:tags]||=[]
  session[:tags] << @hash["tag"]
    unless session[:tags].empty?
    log.error(session[:tags] ) #this keeps printing the current value i was expecting it to print a list of values including the previous
    end
  render :nothing=>true
 end

Ajax

 var myobj={tag:"mytag"};
 $.ajax({
    url: 'ips/receive_tags',
    type: 'post',
    contentType: 'application/json; charset=UTF-8',
    accept: 'application/json',
    dataType: 'json',
    data:JSON.stringify(myobj),
    success: function(res) {
        if (res.ImportResponse !== void 0) {
            console.log('Success: ' + res);
        } else if (res.Fault !== void 0) {
            console.log('Fault: ' + res);
        }
    },
    error: function() {
        console.error('error!!!!');
    }
});
katie
  • 2,921
  • 8
  • 34
  • 51

2 Answers2

1

This sounds like the browser isn't saving cookies, which would explain the behavior you are seeing where the session is reinitialized every time. To confirm this, you can do

print "Session ID: #{request.session_options[:id]}"

in your action and see if the session id changes for each request. If it does, check your browser privacy settings and see if it is saving any cookies.

Scott S
  • 2,696
  • 16
  • 20
  • The session ID keeps changing , it prints the particular current value – katie Dec 07 '12 at 17:10
  • And i just checked my browser settings ,it does save cookies, I am using firefox, says `Firefox will remember history`.Did you try in your environment to see if it works for you? – katie Dec 07 '12 at 17:19
  • Yes, `session[:spike] ||= []` `session[:spike] << params[:spike_param]` works fine for me - it appends `params[:spike_param]` exactly as expected. You might try a different browser, or go to Firefox Preferences > Privacy and click remove individual cookies. If you search for "localhost" here you should have one for your application. – Scott S Dec 07 '12 at 17:41
  • I just tried in chrome , it does the same thing, so it seems like the problem is in the code not browser. – katie Dec 07 '12 at 18:40
  • If the session id changes each request, that really indicates that rails is generating a new session for each request, you just have to figure out why. Is your session set to expire? Look for a line in your application.rb like `config.action_controller.session = {:expire_after => 60*60}` – Scott S Dec 07 '12 at 18:44
  • There is only `Myapp::Application.config.session_store :cookie_store, key: '_myapp_session'` in session_store.rb – katie Dec 07 '12 at 19:02
  • The only other idea I have is that there is something about your AJAX request that is preventing the browser from sending the cookie information. Can you either post that code, or try doing the request without the AJAX and see if it works? – Scott S Dec 07 '12 at 19:18
  • I added my ajax function above – katie Dec 07 '12 at 19:28
  • Have a look at this question -http://stackoverflow.com/questions/10230341/http-cookies-and-ajax-requests-over-https – Scott S Dec 07 '12 at 19:31
  • Thank you very much for your help scott, i have updated the answer below. – katie Dec 07 '12 at 20:48
1

Finally i figured it out, The problem is i wasn't setting the request header for the token before sending ajax call so Rails was receiving data without the token, thus kept assuming it is a new object for every request.You can read more here.To set the request header add

  beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
 }

Below is my ajax function that works

var myobj={tag:"mytag"};
$.ajax({
url: 'ips/receive_tags',
type: 'post',
contentType: 'application/json; charset=UTF-8',
accept: 'application/json',
dataType: 'json',
data:JSON.stringify(myobj),
 beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
 }
 success: function(res) {
    if (res.ImportResponse !== void 0) {
        console.log('Success: ' + res);
    } else if (res.Fault !== void 0) {
        console.log('Fault: ' + res);
    }
 },
 error: function() {
    console.error('error!!!!');
 }
});
Community
  • 1
  • 1
katie
  • 2,921
  • 8
  • 34
  • 51
  • Interesting. I've never run into this, but its something to keep in mind. Glad you got it working. – Scott S Dec 07 '12 at 20:52