【Rails6.0】ポートフォリオに必須な「かんたんログイン」実装手順

# 概要

Railsでアプリを作成する際、deviseを用いてログイン機能を実装する方は多いかと思います。
中でも、``ポートフォリオには「かんたんログインをつけよう！」``と耳にした方も多いかと。

しかし、私の経験談として、``実装には結構苦労しました``。
理由としては、シンプルに``「devise関連で、知らなかったことをやる必要があったから」``です。

なので今回の記事では、

* deviseのコントローラをいじらなきゃいけないの？
* ルーティングはどうやって設定する？

このあたりを整理しつつ、「かんたんログイン実装手順」をアウトプットしたいと思います。

なお、この記事はこちらの素晴らしい記事を参考にしています。
YouTubeでの詳しい解説もありますので、ぜひ御覧ください。

<a href="https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104">Qiita | 簡単ログイン・ゲストログイン機能の実装方法（ポートフォリオ用）</a>

<br>

# 環境

* macOS Catalina 10.15.6
* ruby 2.6.5
* Rails 6.0.3.4
* MySQL : 5.6.47
* devise : 4.7.3

<br>

# 実装の流れを確認

実装に入る前に、まず``かんたんログインの流れ``をおさえましょう。

```:かんたんログインの流れ
1. かんたんログインボタンクリック
2-1. 任意のメアド(guest@gmail.com)がusersテーブルにない場合は他カラムを追加しユーザー作成
2-2. 任意のメアド(guest@gmail.com)がusersテーブルにある場合はそれを取得
3. 作成・取得したユーザーでログイン
4. 好きなページにリダイレクト(大体はトップページ)
```

つまり、必要なのは次の工程です。

```:必要な工程
1. ルーティングにかんたんログイン用コントローラのパスを設定
2. かんたんログイン用コントローラーを作成
3. リンクをビューに設置
```

この工程に沿って実装していきます。

<br>

# 実装 : ファイルを3つ編集すればOK

それでは、``ルーティング→コントローラ→ビューの順番で実装していきます``。

<br>

## 1. かんたんログイン用ルーティングの設定

ルーティングファイルに以下の記述を追加して下さい。

```routes.rb
devise_scope :user do
  post 'users/guest_sign_in', to: 'users/guest_sessions#new_guest'
end
```

これにより、次のルーティングが生成します。

| Prefix | Verb | URI Pattern | Controller#Action |
|:-:|:-:|:-:|:-:|
|  users_guest_sign_in | POST  | /users/guest_sign_in  |  users/guest_sessions#new_guest |

この内容を整理します。

* post, users_guest_sign_in_pathで
* ``app/controllers/users/guest_sessions_controller.rb``の
* ``new_guestアクション``を指定

というわけで、指定したディレクトリにコントローラを作成して、かんたんログインアクションを実装しましょう。

<br>

## 2. かんたんログイン用コントローラの作成

``app/controllers/users/guest_sessions_controller.rb``に``new_guest``アクションを実装していきます。

* 名前空間とRailsの決まりごとに従ってクラス名を選択
* DeviseのSessionsControllerを継承
* ``guest@gmail.com``の有無でユーザーの作成or取得を変更

以上の点に注意しましょう。

```app/controllers/users/guest_sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  def new_guest
    user = User.find_or_create_by!(email: "guest@gmail.com") do |user|
      # ブロックで必要カラムを追加(自分の場合はnicknameを追加)
      user.nickname = "テストユーザー"
      user.password = SecureRandom.urlsafe_base64
      # user.confirmed_at = Time.now  # Confirmable を使用している場合は必要
    end
    # ログイン(deviseのメソッド)
    sign_in user
    # トップページへリダイレクト
    redirect_to root_path
  end  
end
```

``find_or_create_by!``は次のようなメソッドです。

* find_by(カラム: 値)で該当するレコードを取得
* 見つからない場合は、createで新規レコードを作成
* ! は例外を発生させる記述 (! がない場合は、ログインされないままただリダイレクトされる)

ちなみに、今回は実装するコードについての示すのが目的なので、名前空間とパスワードの部分については以下の記事を見て補完して下さい (なお、Qiitaは僕が書いた記事です)。

* <a href="https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html">Rubyリファレンスマニュアル | SecureRandomモジュール</a>
* <a href="https://qiita.com/keisukesaito/items/170f1ad0863e94cfd7dc">Qiita | 【Rails/ルーティング】自作したディレクトリ内のコントローラを参照する方法</a>
* <a href="https://qiita.com/keisukesaito/items/6ec166fdaf5b77a058d4">Qiita | 【Ruby/namespace】Rubyでよく見る「:: ←これ」を深ぼる</a>

<br>

## 3. ビューにリンクを設置

かんたんログインボタンを実装したいビューにリンクを設置しましょう。
僕のアプリの場合は、トップページに以下のコードを追加しました。

```erb:トップページ
<%= link_to 'ゲストログイン', users_guest_sign_in_path, method: :post %>
```

これで完了です！
(以下のGIFでは自分のアプリ用に詳細を変更しています)
[![Image from Gyazo](https://i.gyazo.com/9df7c0541deee845271b13f6d02f91c5.gif)](https://gyazo.com/9df7c0541deee845271b13f6d02f91c5)

<br>

## 4. (補足) 一部をUserモデルに移植する

DBとやりとりしてレコードを取得・生成するのはモデルの仕事です。
なので次のように切り離すとベターかと思います。

```app/controllers/users/guest_sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  def new_guest
    user = User.guest
    # ログイン(deviseのメソッド)
    sign_in user
    # トップページへリダイレクト
    redirect_to root_path
  end  
end
```

```app/models/user.rb
class User < ApplicationRecord

# （略）

  def self.guest
    find_or_create_by!(email: "guest@gmail.com") do |user|
      user.nickname = "テストユーザー"
      user.password = SecureRandom.urlsafe_base64
    end
  end
end
```

<br>

# まとめ

* かんたんログイン実装には、以下のファイルを作成or編集すればOK
    * かんたんログインアクションへのルーティング
    * deviseコントローラを継承した「かんたんログイン用コントローラ」
    * ボタンを設置したいビュー

いろんな記事があると思いますが、基本はこちらに示したとおりなので、ぜひ参考にして下さい！