加载会话的力度如何?

我正在开发一个需要使用会话ID信息的应用程序。 我的会话存储在cookie中。 我遇到的问题是,当用户第一次访问该站点时,我的会话无法立即供控制器使用。 我想我可能会遗漏一些关于如何在Rails中初始化会话的内容。 但我认为会话未加载的事实因为这是session.inspect的输出:

 # 

以下是如何使用Rails 3.2.11ruby 1.9.3重现问题:

使用test控制器创建新应用程序:

 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 

尝试获取该控制器中的会话ID:

 class TestController < ApplicationController def index puts session[:session_id] puts session.inspect end end 

添加所需的路线:

 MyApp::Application.routes.draw do resources :test end 

然后访问应用程序并查看它的作用:

 rails server 

得到: http://localhost:3000/test

这是控制台中的输出:

 # 

然后再次http://localhost:3000/test ,这次我们有一个会话:

 400706c0b3d95a5a1e56521e455075ac {"session_id"=>"400706c0b3d95a5a1e56521e455075ac", "_csrf_token"=>"Euaign8Ptpj/o/8/ucBFMgxGtiH7goKxkxeGctumyGQ="} 

我找到了一种强制会话初始化的方法。 访问会话显然不会强制初始化,但会写入会话。 我现在在控制器中做的是:

 class MyController < ApplicationController protect_from_forgery def index session["init"] = true do_stuff end end 

我仍然不确定这是否应该被视为Rails中的正常行为。 我不得不写入会话以强制初始化。 阅读应该足够了。

我同意@joscas的答案,但我没有写一个值,而是删除它没有冗余数据。

 class MyController < ApplicationController protect_from_forgery def index session.delete 'init' do_stuff end end 

会话也是这样加载的。

注意:确保不要在应用程序中使用要删除的密钥。

以下是ActionDispatch :: Session的一些相关代码:

  def [](key) load_for_read! @delegate[key.to_s] end private def load_for_read! load! if !loaded? && exists? end 

这意味着只要通过[]键访问任何值,就会加载会话对象。

我真的不明白你的问题。 如果您需要用户在能够访问该站点之前注册或登录,则应该没有问题。 创建用户时,他的信息会立即存储在cookie中。 例如:

用户控制器:(通过用户注册#new)

 def create @user = User.new(params[:user]) if @user.save cookies.permanent[:remember_token] = user.remember_token redirect_to root_path, notice: "Thank you for registering!" else render :new end end 

会话控制器:(通过会话#new登录)

  def create user = User.find_by_email(params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) cookies.permanent[:remember_token] = user.remember_token redirect_to root_path, notice: "Logged in." else flash.now.alert = "Email or password is incorrect." render :new end end