加载会话的力度如何?

sub*_*ing 15 session ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

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

#<Rack::Session::Abstract::SessionHash:0x15cb970 not yet loaded>
Run Code Online (Sandbox Code Playgroud)

以下是如何使用Rails 3.2.11和重现问题ruby 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
Run Code Online (Sandbox Code Playgroud)

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

class TestController < ApplicationController
  def index
    puts session[:session_id]
    puts session.inspect
  end
end
Run Code Online (Sandbox Code Playgroud)

添加所需的路线:

MyApp::Application.routes.draw do
  resources :test
end
Run Code Online (Sandbox Code Playgroud)

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

rails server
Run Code Online (Sandbox Code Playgroud)

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

这是控制台中的输出:

#<Rack::Session::Abstract::SessionHash:0x3fd10f50eea0 not yet loaded>
Run Code Online (Sandbox Code Playgroud)

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

400706c0b3d95a5a1e56521e455075ac
{"session_id"=>"400706c0b3d95a5a1e56521e455075ac", "_csrf_token"=>"Euaign8Ptpj/o/8/ucBFMgxGtiH7goKxkxeGctumyGQ="}
Run Code Online (Sandbox Code Playgroud)

sub*_*ing 20

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

class MyController < ApplicationController
  protect_from_forgery
  def index
    session["init"] = true
    do_stuff
  end
end
Run Code Online (Sandbox Code Playgroud)

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


zet*_*tic 7

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

 def [](key)
    load_for_read!
    @delegate[key.to_s]
  end

  private

  def load_for_read!
    load! if !loaded? && exists?
  end
Run Code Online (Sandbox Code Playgroud)

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


Laz*_*dis 7

我同意@joscas的答案,但我没有写一个值,而是将其删除,因为没有冗余数据.

class MyController < ApplicationController
  protect_from_forgery
  def index
    session.delete 'init'
    do_stuff
  end
end
Run Code Online (Sandbox Code Playgroud)

会话也以这种方式加载.

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