Railsでテストアカウントでの簡単ログインの実装方法

#はじめに

ポートフォリオで実装必須な、「テストアカウントでの簡単ログイン」
ポートフォリオくらいでしか使用しないため、記事が少なく、deviseのコントローラ作成方法、エラーの対処法についても、いろんな記事に散らばっていたので、まとめていきます。

どなたかの参考になれば幸いです！

また、私自身、参考記事を元に手探りで実装したので、
誤っている部分があればご指摘いただけますと幸いです:hatched_chick:


#開発環境
- Ruby  2.5.1
- Rails 5.0.7.2


#もくじ
1.　devise用コントローラーの作成
　　(1)コントローラ作成コマンド
　　(2)作成したコントローラの確認
　　(3)ルーティング の設定
2.　SessionsControllerの編集
　　(1)Userモデルにクラスメソッドguestメソッドを作成
　　(2)コントローラにnew_guestアクションを定義
　　(3)ハマりポイントを解説
3.　参考記事


#１.devise用コントローラーの作成

ログインするためのメソッドを記載するコントローラが必要なので、作成します。

deviseの導入方法が不明な方は、こちらを参考にしてください。
(最初〜「４.viewの編集」まででOKです。)
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)

##（１）コントーラーの作成
ターミナルで、簡単ログインを導入したいアプリのディレクトリに移動。
以下コマンドを実行。

```ruby:ターミナル
$rails g devise:controllers users
```

##（２）作成したコントローラを確認

上記コマンドで、「app/controllers/users」ディレクトリの中に、以下４つのコントローラができたことを確認します。

- confirmations_controller.rb
- passwords_controller.rb
- registrations_controller.rb　（ユーザー新規登録に関するコントローラ）
- sessions_controller.rb　（ログインに関するコントローラ）

今回は、sessions_controller.rbを使用します。

##（３）ルーティングの設定

以下、コードを**追記**してください。

```routes.rb

  devise_for :users, :controllers => {
    :registrations => 'users/registrations',
    :sessions => 'users/sessions',
   }

  devise_scope :user do
    get "sign_in", :to => "users/sessions#new"
    get "sign_out", :to => "users/sessions#destroy" 
    post 'users/guest_sign_in', to: 'users/sessions#new_guest'
  end
```
ポイント

- **「resources :users, only: :show」**の記述があるときは、上記コードより**下に記述。**
（上に書くとエラーになります。2(3)ハマりポイントで説明します。）
- devese_for :users　の記述がすでにある時は、**削除**。


#2.SessionsControllerの編集
さて、ここから、簡単ログインを実装します。

##(1)Userモデルにクラスメソッドguestを作成。

```user.rb
  def self.guest
    find_or_create_by(email: "test@com") do |user|
      user.password = Rails.application.secrets.test_account_pass
    end
  end
```
- クラスメソッドなので、メソッド名にselfがつきます。

- find_or_create_byメソッドを使用することで、テストアカウントが削除されてしまってもエラー発生を防ぐことができます。
（テストアカウントが存在すれば、find_byメソッドとして（）内の検索ワードで、アカウントを検索。
存在しなければcreateメソッドとして機能し、（）内を属性値として、アカウントを作成してくれます。）

- パスワードはuser.passwordの記述で設定。
パスワードは、環境変数に格納しました。
（テストアカウントなので、パスワードが漏れても問題ないのですが、念の為。
環境変数の設定の仕方は、別記事にまとめます。）

- パスワードを直打ちする場合は、「user.password = 12345678」のように、記載します。


##(2)sessions_controller.rbに、new_guestメソッドを定義

```sessions_controller.rb
  def new_guest
    user = User.guest
    sign_in user
    redirect_to root_path, notice: "Thank you for your testing!"
  end
```
- (1)で作成したguestメソッドを使用。テストアカウントのemail、password情報を持ったuserを作成。
- deviseのメソッドであるsigh_inメソッドでログイン
- redirect先を決定。ログインが成功したときの、メッセージをnotice: 以下の記載。（ここでは、「notice: "Thank you for your testing!"」）



##(✴︎)ハマりポイントの解説
上記（１）（２）を設定して意気揚々とブラウザを開いたところ、以下のエラー！！

<img width="582" alt="スクリーンショット 2020-03-31 12.45.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527423/faf09735-0759-886e-f31c-9386b7cc7c9b.png">

ターミナルを見ると、無限ループが発生しているようです。
<img width="488" alt="スクリーンショット 2020-03-31 12.49.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527423/8a8ee6f1-bed4-6542-dd7a-89c497ffc370.png">


これは、ルーティングを書く順番が誤っているためのエラーです。

sing_inアクションを実行すると、users#showのルーティングが上にあるため、/users/の後に続く文字列を、idだと認識。
そのため、usersのshowアクション（users/:id）が実行されてしまいます。
でも、showアクションはログインしていないと、閲覧できないので、またログイン画面→users#showの無限ループになるようです。

「resources :users, only: :show」 の位置を以下の変更してあげたら、
無事に解消しました。

[「localhost でリダイレクトが繰り返し行われました。」はルーティングのせいだった、Ruby on Rails エラーの分析](https://ysk-pro.hatenablog.com/entry/2018/02/19/225131)

```routes.rb

  devise_for :users, :controllers => {
    :registrations => 'users/registrations',
    :sessions => 'users/sessions',
   }

  devise_scope :user do
    get "sign_in", :to => "users/sessions#new"
    get "sign_out", :to => "users/sessions#destroy" 
    post 'users/guest_sign_in', to: 'users/sessions#new_guest'
  end

  resources :users, only: :show 
　##devise_for :usersや、deveise_scope :userより下に書くのがポイント
```

##（３）簡単ログインのためのリンクをはる。
最後に、ヘッダー　or　トップページ　or　ログインページに以下のリンクを貼り付けてあげると完成です！
（私は、ログインページに貼りました）

```sessions/new.html.haml
  -#hamlの場合
  = link_to 'Log in for TEST', users_guest_sign_in_path, method: :post

  -#htmlの場合
  <%= link_to 'Log in for TEST', users_guest_sign_in_path, method: :post %>

```

　![login画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527423/9f483b76-561a-798b-c3a0-f4bea1b1338b.png)


以上で簡単ログインの実装は完了です！！

その他、テストユーザーの削除や、属性の変更をできないようにする方法もありますので、
知りたい方は、ぜひ以下の記事を参考にしてください！

[ゲストログイン・簡単ログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)


最後まで、ご覧いただき、ありがとうございました。

#参考記事
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)
[Deviseの設定手順をまとめてみた。 その2　ViewとControllerのカスタマイズ編](https://qiita.com/aplifyjp/items/f991d54ff527edb844d9)
[ゲストログイン・簡単ログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)
[「localhost でリダイレクトが繰り返し行われました。」はルーティングのせいだった、Ruby on Rails エラーの分析](https://ysk-pro.hatenablog.com/entry/2018/02/19/225131)