Ruby on Rails チュートリアル(第4版)　第9章

##9.1.1　演習
1.コンソールを開き、データベースにある最初のユーザーを変数userに代入してください。その後、そのuserオブジェクトからrememberメソッドがうまく動くかどうか確認してみましょう。また、remember_tokenとremember_digestの違いも確認してみてください。

```
>> user = User.first
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-07-10 15:10:18", updated_at: "2020-07-10 15:10:18", password_digest: "$2a$10$VICUYjma4CkWdl2WFBg.FenXS3mnUPnWYT8YmGUOYS2...", remember_digest: nil>
>> user.remember
   (0.1ms)  begin transaction
  SQL (3.8ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2020-07-16 12:46:33.559321"], ["remember_digest", "$2a$10$FATE86//OHcrZ/.axSRphOFJWoi4upmWAfD7Slf.vu0pZFtDQHA7y"], ["id", 1]]
   (9.6ms)  commit transaction
=> true
>> user.remember_token
=> "cZqAhN-e718FgLa6zK4uFQ"
>> user.remember_digest
=> "$2a$10$FATE86//OHcrZ/.axSRphOFJWoi4upmWAfD7Slf.vu0pZFtDQHA7y"
```

2.リスト 9.3では、明示的にUserクラスを呼び出すことで、新しいトークンやダイジェスト用のクラスメソッドを定義しました。実際、User.new_tokenやUser.digestを使って呼び出せるようになったので、おそらく最も明確なクラスメソッドの定義方法であると言えるでしょう。しかし実は、より「Ruby的に正しい」クラスメソッドの定義方法が２通りあります。1つはややわかりにくく、もう1つは非常に混乱するでしょう。テストスイートを実行して、ややわかりにくいリスト 9.4の実装でも、非常に混乱しやすいリスト 9.5の実装でも、いずれも正しく動くことを確認してみてください。ヒント: selfは、通常の文脈ではUser「モデル」、つまりユーザーオブジェクトのインスタンスを指しますが、リスト 9.4やリスト 9.5の文脈では、selfはUser「クラス」を指すことにご注意ください。わかりにくさの原因の一部はこの点にあります。
　省略

##9.1.2　演習
1.ブラウザのcookieを調べ、ログイン後のブラウザではremember_tokenと暗号化されたuser_idがあることを確認してみましょう。
　省略

2.コンソールを開き、リスト 9.6のauthenticated?メソッドがうまく動くかどうか確かめてみましょう。

```
>> user = User.first
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-07-10 15:10:18", updated_at: "2020-07-16 13:04:30", password_digest: "$2a$10$VICUYjma4CkWdl2WFBg.FenXS3mnUPnWYT8YmGUOYS2...", remember_digest: "$2a$10$XXupnj/IA6t2whC.1/UTHuvIkULxHDb0VZIlfAnEFZH...">
>> user.remember
   (0.1ms)  begin transaction
  SQL (3.9ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2020-07-16 13:06:46.425361"], ["remember_digest", "$2a$10$Rf64G/FTJ/.z/aqlD0qfluAqSxYl1xmmkS0Wawx0ZDjj41X3k1y0O"], ["id", 1]]
   (6.3ms)  commit transaction
=> true
>> user.authenticated?(user.remember_token)
=> true
```

##9.1.3　演習
1.ログアウトした後に、ブラウザの対応するcookiesが削除されていることを確認してみましょう。
　省略

##9.1.4　演習
1.リスト 9.16で修正した行をコメントアウトし、２つのログイン済みのタブによるバグを実際に確かめてみましょう。まず片方のタブでログアウトし、その後、もう１つのタブで再度ログアウトを試してみてください。
　省略
2.リスト 9.19で修正した行をコメントアウトし、２つのログイン済みのブラウザによるバグを実際に確かめてみましょう。まず片方のブラウザでログアウトし、もう一方のブラウザを再起動してサンプルアプリケーションにアクセスしてみてください。
　省略
3.上のコードでコメントアウトした部分を元に戻し、テストスイートが red から greenになることを確認しましょう。

##9.2　演習
1.ブラウザでcookies情報を調べ、[remember me] をチェックしたときに意図した結果になっているかどうかを確認してみましょう。
　省略
2.コンソールを開き、三項演算子を使った実例を考えてみてください (コラム 9.2)。

```
>> number = 3
=> 3
>> puts number == 3 ? "3!" : "not 3!"
3!
=> nil
>> number = 2
=> 2
>> puts number == 3 ? "3!" : "not 3!"
not 3!
=> nil
```

##9.3.1　演習
1.リスト 9.25の統合テストでは、仮想のremember_token属性にアクセスできないと説明しましたが、実は、assignsという特殊なテストメソッドを使うとアクセスできるようになります。コントローラで定義したインスタンス変数にテストの内部からアクセスするには、テスト内部でassignsメソッドを使います。このメソッドにはインスタンス変数に対応するシンボルを渡します。例えばcreateアクションで@userというインスタンス変数が定義されていれば、テスト内部ではassigns(:user)と書くことでインスタンス変数にアクセスできます。本チュートリアルのアプリケーションの場合、Sessionsコントローラのcreateアクションでは、userを (インスタンス変数ではない) 通常のローカル変数として定義しましたが、これをインスタンス変数に変えてしまえば、cookiesにユーザーの記憶トークンが正しく含まれているかどうかをテストできるようになります。このアイデアに従ってリスト 9.27とリスト 9.28の不足分を埋め (ヒントとして?やFILL_INを目印に置いてあります)、[remember me] チェックボックスのテストを改良してみてください。
 
```ruby:/app/controllers/sessions_controller.rb
  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      redirect_to @user
```

　asset_equal　期待する値, 実際の値　と書く。

```ruby:/test/integration/users_login_test.rb
  test "login with remembering" do
    log_in_as(@user, remember_me: '1')
    assert_equal cookies['remember_token'], assigns(:user).remember_token
  end
```

##9.3.2　演習
1.リスト 9.33にあるauthenticated?の式を削除すると、リスト 9.31の２つ目のテストで失敗することを確かめてみましょう (このテストが正しい対象をテストしていることを確認してみましょう)。
　省略

##毎度のエラー
`$heroku maintenance:on`で`heroku command not found`のエラー。
Cloud9ログインしなおすと毎回エラー出るのかな。

`nvm install node`
`npm install -g heroku-cli`

これで治るので無事デプロイ完了。

##メモ
- 三項演算子　`論理値? ? 何かをする : 別のことをする`