rails学習　7日目その４

#Railsチュートリアル　第8章
##8.1.1 Sessionsコントローラー
ログイン、ログアウト関連はsessionsコントローラーで定義する

今回のログインのコードは

```
form_for(:session, url:login_path)
入力フォームが続く
```
と書いている（前回はform_for(@user)だった）
今回は入力フォームに記入した値を取得するために:sessionを使う。そうすることで

```
form_for(:session, url:login_path)
入力フォームが続く

パスワード：〇〇〇〇〇〇
アドレス：✖️✖︎@example.com
```
と書くと
session{password:"〇〇〇〇〇〇",email:"✖️✖︎@example.com"}
という情報が取得できる。これを応用すると
params[:session][:password]=〇〇〇〇〇〇
params[:session][email]=✖️✖︎@example.com
とこのようにsessionに入れてしまえばparamsを使っていくらでも出し入れができる。

##8.1.3　ユーザの検索と認証
上記のsessionを使いログインのアクションを作っていく

```ruby
def create
  user = User.find_by(params[:session][:email].downcase)
  if user&&user.authenticate(parasm[:session][:password])
  ・・・
  else
  ・・・
  end
end
```

>user = User.find_by(params[:session][:email].downcase)

まずはユーザーをログインする上でログイン画面で記入したアドレス（session[:email]）の小文字に変換したもの（downcase）が存在するユーザーをuserとする

> if user&&user.authenticate(parasm[:session][:password])

もし上記で定義したユーザーが存在する。かつ（&&）ユーザーパスワードと記入したパスワードの暗号化したもの（authenticate(params[:session][:password]))がtrueならifを実行する。

##8.1.4　フラッシュメッセージを表示する
>flashの特徴

```ruby
flash[:success] = '〇〇〇〇〇〇'
redirect_to ・・・

flash.now[:success] = '〇〇〇〇〇〇'
render ・・・
```
flashメッセージを表示させてからredirect_toだと更新されてHTTPを通りフラッシュメッセージは消えるが、renderだと直接ビューへアクセスし、HTTPを通らないので更新されずメッセージが残ったままとなる。なのでこの場合はflash.nowで一回だけフラッシュメッセージを表示させるようにする。

##8.2　ログイン
アプリはログインという状態を維持しながら様々な操作を行う。つまりログインは様々な操作と関連付けて機能している。なのでログインという動作を一つのヘルパーメソッドにまとめてどのビューでも使えるようにし、Applicationコントローラーと紐づけをし、どのコンテローラでも使えるようにする。

##8.2.1　ログインメソッド

このコードでユーザーIDが生成される

```
session[:user_id] = user.id
```
今のuserのid(user.id)をsession[:user_id]に代入する。この操作をヘルパーメソッドとしてまとめる

```ruby
def log_in(user)
  session[:user_id] = user.id
end
```

![IMG_0570.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815476/b490e310-8871-7b0f-65a6-1c8b2c0ec45b.jpeg)

ログインするときのアクションdef createにlog_inヘルパーメソッドを記入
redirect_to userでログインしたユーザーの詳細画面に飛ぶ。

ログインしている状態ではsession[:user_id] = user.idがなり立つということになる
次はそれを利用してログイン中のユーザーの情報全てを取得する

##8.2.2　現在のユーザー

```ruby
def current_user
  if ＠current_user.nil?
    @current_user = User.find_by(id:session[user_id])
  else
    @current_user
  end
end
```

現在ログインしているユーザー情報を＠current_userとする。
もし@current_userがいなければ（nil?）ifから下を返す（ifから下はsession[:user_id]つまりセッションしているidのユーザーを探してそれを@current_userにするというもの）。そうじゃなければ（@current_userがいる場合は）@current_userを返す

省略した書き方にすると

```ruby
def current_user
  if session[:user_id]
    @current_user ||= User.find_by(id:session[user_id])
  end
end
```
となる

##8.2.3　レイアウトリンクを変更する
これでログイン状態が保持されるので次はログインしている状態としていない状態で表示するリンクを変える。

![IMG_0572.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815476/bcd9b1c1-fe36-f770-ac90-ce56e884ec93.jpeg)

ログインしているかどうかを判断するには@current_userが存在するかどうかということに置き換えることができる。つまり!current_user.nil?でcurrent_userはいますか？という形になる。これをヘルパーメソッドでまとめる

```ruby
def logged_in?
 !current_user.nil?
end
```
をヘルパーメソッドに書いた。
##8.3　ログアウト
session[:user_id]がログイン状態だったのでログアウトはsession[:user_id]を消したら(deleteしたら)良い。つまりログアウトもヘルパーメソッドで書くと

```ruby
def log_out
  session.delete[:user_id]
  @current_user = nil
end
```
session.delete[:user_id]とすることでログアウトできる。
そして@current_user = nilとすることでログイン中のユーザーもいなくなる。
@current_user = nilがないとログアウトしてもデータ上ではログインしたままの状態になっている

※@current_userはログイン中のユーザー本人で、current_userはログインユーザーを作成するというアクションのこと