deviseを使ったユーザー管理機能の実装

## deviseを使ったユーザー管理機能（ログイン・ログアウト）の実装手順
今回はトップページの作成も合わせて行います。
トップページを既に作成済みの方は、**ログイン機能の実装**のみお読みください。
###作業の流れ
####・トップページの作成
1. homesコントローラ作成
2. homesコントローラの編集
3. トップページのビュー作成
4. ルーティングの編集

####・ログイン機能の実装
1. gem 'devise' のインストール
2. deviseの設定ファイル作成
3. ログイン機能付きUserモデルの作成
4. データベースに反映



## トップページの作成
早速作業に入りましょう

#### 1. homesコントローラの作成  
今回は例として `homesコントローラ` を作成します。

```:ターミナル
$ rails g controller homes

*コマンドを実行すると以下のようなものが作成されます。

Running via Spring preloader in process ****
      create  app/controllers/homes_controller.rb
      invoke  erb
      create    app/views/homes
      invoke  test_unit
      create    test/controllers/homes_controller_test.rb
      invoke  helper
      create    app/helpers/homes_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/homes.coffee
      invoke    scss
      create      app/assets/stylesheets/homes.scss
```

#### 2. homesコントローラの編集  
続いて先ほど作成された、`homes_controller.rb` に `indexアクション` を定義します。

```ruby:app/controllers/homes_controller.rb
class HomesController < ApplicationController
    def index
    end
end

```
#### 3. トップページのビュー作成
次に `homesコントローラ`の`indexアクション`が呼ばれた際に返すビューを用意します。
app/views内のhomesディレクトリに`index.html.erb`を新規作成してください。
<img src="https://i.gyazo.com/1c902dc61dc1b4d718c805385b8acce0.png" alt="Image from Gyazo" width="300"/>
後でちゃんとこのページが呼ばれているか確認するため、`index.html.erb`にテキストを入力しておきます。
<img src="https://i.gyazo.com/8ceb43fbc96bc2790a3109c21826c9c0.png" alt="Image from Gyazo" width="480"/>

#### 4. ルーティングの編集
トップページを表示するためのルーティングを設定します。

```ruby:config/routes.rb
Rails.application.routes.draw do
    root to: "homes#index"
end
```

これで **トップページの作成** は完了です。
最後にローカルサーバを起動して、ちゃんと表示されるか確認しておきましょう。
`rails s`を実行してからこちらをクリック➡️　[http://localhost:3000/](http://localhost:3000/)
白くて分かりづらいですが、以下のような画面が表示されればOKです。
<img src="https://i.gyazo.com/3e6c721f3868672910dc998a35e8944f.png" alt="Image from Gyazo" width="500"/>

## ログイン機能の実装
それでは **ログイン機能の実装** に入ります。

#### 1. gem 'devise' のインストール
まずは今回ログイン機能の実装に使用する`'devise'`というgemをインストールします。
Gemfileの最後の行に`gem 'devise'`を追記してください。

```ruby:Gemfile
====== 省略 ======

gem 'devise'
```

続けてターミナルでgemのインストールを実行します。

```:ターミナル
$ bundle install
```
補足）`gem list`コマンドを実行し、きちんとgemがインストールされているか確認しておきましょう。

```:ターミナル
$ gem list

*** LOCAL GEMS ***

==== 省略 ====
debug_inspector (0.0.3)
devise (4.7.1)     ⬅️deviseがインストールされていればOK
did_you_mean (1.2.0)
diff-lcs (1.3)
domain_name (0.5.20190701)
==== 省略 ====

```

#### 2. deviseの設定ファイル作成
次にdeviseを使用する際に必要な設定ファイルを作成します。
deviseに関するファイルなのでdevise専用コマンドを使用します。

```:ターミナル
$ rails g devise:install

Running via Spring preloader in process ****
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
```

#### 3. ログイン機能付きUserモデルの作成
ユーザー情報を登録するためのモデル、マイグレーションファイルなどを作成します。
ここでもdevise専用コマンドを使用します。

```:ターミナル
$ rails g devise user

Running via Spring preloader in process ****
      invoke  active_record
      create    db/migrate/20200404053603_devise_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      insert    app/models/user.rb
       route  devise_for :users

※注意：userの前にmodelをつけるとmodelモデルが作成されてしまいます。
```

上記コマンドを実行すると、自動的に以下のようなルーティングが生成されます。

```ruby:config/routes.rb
Rails.application.routes.draw do
    devise_for :users   ⬅️自動で生成
    root to: "homes#index"
end
```

#### 4. データベースに反映
最後にユーザーの情報を登録できるようにするため、マイグレーションファイルをデータベースに反映します。

```:ターミナル
$ rails db:migrate

== 20200404053603 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0122s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0113s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0128s
== 20200404053603 DeviseCreateUsers: migrated (0.0366s) =======================
```
以上でログイン機能の実装は完了です。 
早速確認してみましょう。

ローカルサーバを起動し、URLの末尾に`users/sign_up`と入力して、新規登録画面を確認しましょう。以下のような画面が表示されます。
<img src="https://i.gyazo.com/160fde53ddef26c50d245cfcdaadad42.png" alt="Image from Gyazo" width="300"/>
続いて、URLの末尾を`users/sign_in`に変更するか、sign_up画面のlog inのリンクをクリックして、ログイン画面を確認しましょう。
<img src="https://i.gyazo.com/b4db19788917a40e50c043e2363daa3d.png" alt="Image from Gyazo" width="300"/>

画面が確認できればOKです。お疲れ様でした。
また、ここまでお読み頂きありがとうございました。

## 追加補足

補足１） **4. データベースに反映** を忘れていた場合、以下のようなPendingMigrationErrorというエラーが発生してしまいます。要は、データベースに反映されていないマイグレーションファイルが残ってるよ。という意味です。
<img src="https://i.gyazo.com/b094de665a0f96a12099f64f0b185918.png" alt="Image from Gyazo" width="500"/>

補足２）もし rails db:migrate を実行したはずなのに上記のエラー画面が表示される場合は、`rails db:migarate:status` コマンドを実行してマイグレーションの状況を確認しましょう。

```:ターミナル
$ rails db:migrate:status

database: sample_app_development

 Status   Migration ID    Migration Name
--------------------------------------------------
  down    20200404053603  Devise create users

```
補足３）上記のように Status が`down`の場合はきちんとマイグレーションファイルの反映が行われていません。再度`db:migrate` を実行してください。Status が `UP` になればOKです。

補足４）上記のエラーとは別に、もし以下のようなNoMethodErrorというエラーが発生した場合は、ローカルサーバを再起動しましょう。
<img src="https://i.gyazo.com/66ada27463a5bc75079eb3f185bb2905.png" alt="Image from Gyazo" width="500"/>


## 追加実装
ログイン画面へのリンクをつくるのが面倒なので、ログインしていないとトップページにいけないようにしてしまいましょう。追記するのは以下の一点です。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :authenticate_user!  ⬅️この一行を追記
end
```

補足）このままではログアウトができないので、ログアウトのリンクだけ作成しておきます。
`index.html.erb` を以下のように編集しましょう。

```ruby:app/views/homes/index.html.erb
これは"homes#index"ページです。
<br>
ログアウトしますか？
<%= link_to "はい", destroy_user_session_path, method: :delete %>
```

ログイン後のビューは以下のようになります。
<img src="https://i.gyazo.com/f7cabae2fc2a66c22f8efb4ce7d7df17.png" alt="Image from Gyazo" width="400"/>