セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

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は予期しない挙動をとる。と言うのも、rendernewを呼ぶとそれはアクションとは認められないため必然的に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