web-dev-qa-db-ja.com

そのセッションはどの程度強制的にロードされますか?

セッションID情報を使用する必要があるアプリケーションに取り組んでいます。私のセッションはCookieに保存されています。私が抱えている問題は、ユーザーが初めてサイトにアクセスしたときに、コントローラーが私のセッションをすぐに利用できないことです。 Railsでセッションがどのように初期化されるかについて何かが足りないかもしれないと思います。しかし、これはsession.inspectの出力であるため、セッションがロードされないという事実について私は確信しています。

#<Rack::Session::Abstract::SessionHash:0x15cb970 not yet loaded>

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

これがコンソールの出力です。

#<Rack::Session::Abstract::SessionHash:0x3fd10f50eea0 not yet loaded>

それからまたhttp://localhost:3000/testそして今度はセッションがあります:

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

セッションの初期化を強制する方法を見つけました。セッションへのアクセスは明らかに初期化を強制しませんが、セッションへの書き込みは強制します。私がコントローラーで行っていることは、これです。

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

それでも、これがRailsの通常の動作と見なされるべきかどうかはわかりません。初期化を強制するためにセッションに書き込む必要があるのは私には正しく見えません。読書で十分なはずです。

21
joscas

ActionDispatch :: Session :からの関連コードを次に示します。

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

  private

  def load_for_read!
    load! if !loaded? && exists?
  end

これは、[]を介してキーで値にアクセスするとすぐに、セッションオブジェクトがロードされることを意味します。

7
zetetic

@joscasの回答に同意しますが、値を書き込む代わりに、冗長なデータがないように削除します。

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

セッションもこの方法でロードされます。

注:アプリケーションで削除するキーを使用しないようにしてください。

7

私はあなたの質問を本当に理解していません。ユーザーがサイトにアクセスする前に登録またはサインインする必要がある場合は、問題はありません。ユーザーを作成すると、その情報はすぐにCookieに保存されます。例えば:

ユーザーコントローラー:(登録はusers#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

セッションコントローラー:(サインインはsessions#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
0
Peter de Ridder