rails チュートリアル第９章


チェックボックスを作るとトークンを作らなければならないらしい。

1.記憶トークン用のカラムを用意
（新たなデータベースの空欄を作る）
2.ランダムな文字列を生成し、ハッシュ化する
（自分にもわからないように文字列を散らす）

user.rb

```rb
 # ランダムなトークンを返す
  def User.new_token
    SecureRandom.urlsafe_base64
    # 文字列を生成する
  end 
  
   # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    # ランダムな文字列を返す
    self.update_attribute(:remember_digest, User.digest(remember_token))
    # ランダムな文字列をハッシュ化させ、remember_digestのカラムに納める
  end
```
 
3.ハッシュ化した値を、データベースのカラムに保存する
sessions_controller

```rb
 remember user
  #データベースにハッシュ化された　文字列記憶させる
```

```rb
   # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    # ランダムな文字列を返す
    update_attribute(:remember_digest, User.digest(self.remember_token))
    # データベースの値を複数同時に更新
    # ランダムな文字列digestでをハッシュ化させる
    # remember_digest（データベース）のカラムに記憶させる
```

4.ブラウザのcookiesに、暗号化したIDとTokenを保存する
（ブラウザの中にあるcookiesに保存する）
sessions_helper

```rb
   # ユーザーのセッションを永続的にする
  def remember(user)
    #userクラスのrememberメソッドとは違う 
    #こっちは引数を使和なければならない
    user.remember
    # 新たなハッシュ化された文字列を生成
    cookies.permanent.signed[:user_id] = user.id
    # cookiesにID番号を返す
    # .signed ure idを暗号化、複合化する
    cookies.permanent[:remember_token] = user.remember_token
    # rememberは仮想の何かだから次になんかしたら消えるので
    # cookiesにトークンを保存する
  end
```

コントローラで使うrememberメソッド
5.cookiesのIDを使って、ユーザーをデータベースから検索する。
　cookeisのTokenを認証し、同一からセッションを復元する
（ブラウザの中にあるcookiesのユーザーIDとTokenから認証される）

```rb
 # 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
    # データベースのremember_digestとトークンのremember_token
      #を照らし合わせる
  end
```

```rb
def current_user
    if (user_id = session[:user_id])
    # sessionのuser_idを取り出し、返す   
    # nil,falseでないかをチェック つまり空では無いか
      @current_user ||= User.find_by(id: user_id)
      #一回だけデータベースに問い合わせる
    elsif (user_id = cookies.signed[:user_id])
    # 暗号化されたクッキーのユーザーIDがあれば
      user = User.find_by(id: user_id)
      # ユーザーIDでユーザーを検索する
      if user && user.authenticated?(cookies[:remember_token])
      #  ユーザーが存在し、データベースとクッキーのトークンが一致したら
        log_in user
        #log_inメソッドでう
        @current_user = user
      　#任意のデータベースを取得する
      　# メモ化する
      end
    end
  end
```

```
Error:
UserTest#test_authenticated?_should_return_false_for_a_user_with_nil_digest:
BCrypt::Errors::InvalidHash: invalid hash
    app/models/user.rb:43:in `new'
    app/models/user.rb:43:in `authenticated?'
     #authenticatedで失敗
    test/models/user_test.rb:71:in `block in <class:UserTest>'
```

```rb
# 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    # remember_digestが空ならばfalseを返す
    # 先にreturnをすることでエラーを起こさないようにする
    # remember_tokenが空(nil)だから
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
    # データベースのremember_digestとトークンのremember_token
      #を照らし合わせる
  end
```
勉強の内容
1.チェックボックスをLog inフォームに設置
2.CSSでデザインを改善
3.params[:session][:remember_me]をチェックして、
　チェックされていたらrememberメソッドを、
　そうでなければforgeメソッドを使用

```rb
def current_user
    if (user_id = session[:user_id])
    # sessionのuser_idを取り出し、返す   
    # nil,falseでないかをチェック つまり空では無いか
      @current_user ||= User.find_by(id: user_id)
      #一回だけデータベースに問い合わせる
    elsif (user_id = cookies.signed[:user_id])
    # 暗号化されたクッキーのユーザーIDがあれば
      raise
      # 強制的にエラーを起こす
      user = User.find_by(id: user_id)
      # ユーザーIDでユーザーを検索する
      if user && user.authenticated?(cookies[:remember_token])
      #  ユーザーが存在し、データベースとクッキーのトークンが一致したら
        log_in user
        #log_inメソッドでう
        @current_user = user
        #任意のデータベースを取得する
        # メモ化する
      end
    end
  end
```
バグの見つけ方
rails testで成功したらテストで確認できていない

書き損じがあるがこんな感じで進んでいくらしい。