I'm working on an application that needs to use session id information. My session is stored in cookies. The problem I have is that my session is not immediately available to the controller when a user comes to the site for the first time. I think I may be missing something about how sessions are initialized in Rails. But I'm positve about the fact that the session is not loaded because this is the output of session.inspect
:
#<Rack::Session::Abstract::SessionHash:0x15cb970 not yet loaded>
Here is how to reproduce the problem with Rails 3.2.11
and ruby 1.9.3
:
Create a new application with a test
controller:
rails new my_app
cd my_app/
rails g controller test
rm app/assets/javascripts/test.js.coffee
touch app/views/test/index.html.erb
Try to get the session id in that controller:
class TestController < ApplicationController
def index
puts session[:session_id]
puts session.inspect
end
end
Add the needed routes:
MyApp::Application.routes.draw do
resources :test
end
Then access the application and see what it does:
rails server
got to: http://localhost:3000/test
That is the output in the console:
#<Rack::Session::Abstract::SessionHash:0x3fd10f50eea0 not yet loaded>
Then again http://localhost:3000/test
and this time we have a session:
400706c0b3d95a5a1e56521e455075ac
{"session_id"=>"400706c0b3d95a5a1e56521e455075ac", "_csrf_token"=>"Euaign8Ptpj/o/8/ucBFMgxGtiH7goKxkxeGctumyGQ="}
Rails provides a session object for each user that accesses the application. If the user already has an active session, Rails uses the existing session. Otherwise a new session is created. Read more about sessions and how to use them in Action Controller Overview Guide.
Ruby on Rails parses cookies and serializes these files into key-value pairs (hashes) and stores them into a session. What is a session? Session is a type of cookie that is unique to the user and stores information about the user when he/she is logged in.
The rails way of creating a session is just using 'session[:user_id] = user.id'. This will create a session with the user_id. The current_user method will return the current user if there is one or if there is a session present. That means if a user is logged in, the current user will be the that user.
I found a way to force initialization of the session. Accessing the session apparently does not force initialization but writing into the session does. What I do in my controller is this now:
class MyController < ApplicationController
protect_from_forgery
def index
session["init"] = true
do_stuff
end
end
Still I'm not sure if this should be considered normal behavior in Rails. It doesn't look right to me having to write into the session to force initialization. Reading should be enough.
I agree with @joscas answer but instead of writing a value, I'd delete it as to not have redundant data.
class MyController < ApplicationController
protect_from_forgery
def index
session.delete 'init'
do_stuff
end
end
The session is loaded this way too.
Note: Make sure you don't use the key to be deleted in your application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With