ruby チュートリアル8章 メモ
セッションとクッキー
混同しがち(自分だけかも、)HTTPはステートレスなプロトコルなので、セッションのような物を実装するには、状態を保存するものが別に必要なる。それの一つがクッキー。クッキーはユーザのブラウザ内に保存される小さなテキスト。一方セッションはそもそも何かを継続的に行なっているものを指すらしく、接続し続けることもその中の一つと言う解釈でしょうか。
ログインページ
チュートリアルではこれから生成するセッションのコントローラがそのままログインページ系を司どるように作るそうです。言葉にするとわかりにくいので下にそれっぽいルーティングを示します。loginと言うコントローラを作るのではなく、セッションを開始終了のためのページがログイン/ログアウトってイメージですね。なお、セッションコントローラの処理はこれだけでよいので、generate
で無駄なアクションを作ったり、resources
で無駄にルーティングを作るのは避けます。
#config/route.rb get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete '/logout', to: 'sessions#destroy'
renderメソッドとアクション
下のようにflashに値を格納した後にrenderを呼ぶと、flashは予期しない挙動をとる。と言うのも、render
でnew
を呼ぶとそれはアクションとは認められないため必然的にflashの生存時間が1アクション分伸びてしまう。
#app/controllers/sessions_controller.rb def create if ~~ # ユーザーログイン後にユーザー情報のページにリダイレクトする else flash[:danger] = 'Invalid email/password combination' render 'new' end end
flash.now
メソッドを利用することでこれを回避することができる。
flash.now[:danger] = 'Invalid email/password combination'
findメソッドとfind_byメソッド
User.find(session[:user_id])
でユーザ検索を行った場合、ユーザIDが存在していない状況(まだログインしていない、session[:user_id]の値がnilになる状態)だと、例外が発生する。一方User.find_by(id: session[:user_id])
は、例外を発生せずnilを返す。
fixtureとFactorybot
チュートリアルではMinitest利用なのでfixtureを利用しているが、RSpecを使用していならFactorybotでカバーできる。個人的には下のようにしてチュートリアルのテストコードを実装しています。
#spec/controllers/user_controller_spec.rb let(:user){build(:user)} let(:post_create){ post( :create, params: { user: { name: user.name, email: user.email, password: user.password, password_confirmation: user.password_confirmation } })} it 'ユーザが新規に生成される' do expect{post_create}.to change{User.count}.by(1) end