セッションID情報を使用する必要があるアプリケーションに取り組んでいます。私のセッションはCookieに保存されています。私が抱えている問題は、ユーザーが初めてサイトにアクセスしたときに、コントローラーが私のセッションをすぐに利用できないことです。 Railsでセッションがどのように初期化されるかについて何かが足りないかもしれないと思います。しかし、これはsession.inspect
の出力であるため、セッションがロードされないという事実について私は確信しています。
#<Rack::Session::Abstract::SessionHash:0x15cb970 not yet loaded>
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
そのコントローラーでセッション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="}
セッションの初期化を強制する方法を見つけました。セッションへのアクセスは明らかに初期化を強制しませんが、セッションへの書き込みは強制します。私がコントローラーで行っていることは、これです。
class MyController < ApplicationController
protect_from_forgery
def index
session["init"] = true
do_stuff
end
end
それでも、これがRailsの通常の動作と見なされるべきかどうかはわかりません。初期化を強制するためにセッションに書き込む必要があるのは私には正しく見えません。読書で十分なはずです。
ActionDispatch :: Session :からの関連コードを次に示します。
def [](key)
load_for_read!
@delegate[key.to_s]
end
private
def load_for_read!
load! if !loaded? && exists?
end
これは、[]
を介してキーで値にアクセスするとすぐに、セッションオブジェクトがロードされることを意味します。
@joscasの回答に同意しますが、値を書き込む代わりに、冗長なデータがないように削除します。
class MyController < ApplicationController
protect_from_forgery
def index
session.delete 'init'
do_stuff
end
end
セッションもこの方法でロードされます。
注:アプリケーションで削除するキーを使用しないようにしてください。
私はあなたの質問を本当に理解していません。ユーザーがサイトにアクセスする前に登録またはサインインする必要がある場合は、問題はありません。ユーザーを作成すると、その情報はすぐに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