[Rails]ゲストログイン機能

# 目次
[環境](#環境)
[仕様](#仕様)
[コントローラ作成](#コントローラ作成)
[ルーティング](#ルーティング)
[モデル](#モデル)
[ゲストログインボタン作成](#ゲストログインボタン作成)
[プロフィール編集できなくする](#プロフィール編集できなくする)
[最後に](#最後に)

# 環境
mac OS Ventura 13.3
cloud9
Rails 6.1.7
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
git version 2.39.2
devise導入
Bootstrap

# 仕様
- ゲストログインボタンを配置する
- ゲストログインボタンを押下すると、ゲストユーザーでログイン状態になり、ユーザー詳細画面へと遷移する
- nameとemailはあらかじめ決めておく
- ゲストログインユーザーはプロフィール編集画面への遷移ボタンを配置しない
- ゲストログインユーザーはプロフィール編集画面に遷移できない（URL直接入力を含む）
- モデルはUser

# コントローラ作成
まずゲストログイン用のコントローラを作成します。
`app/controllers`の配下に、`users`フォルダを作成、作成した`users`フォルダに`sessions_controller.rb`を作成します。
sessions_controller.rbには以下のように記述します。
```sessions_contoroller.rb
class Users::SessionsController < Devise::SessionsController
  def guest_sign_in
    user = User.guest
    sign_in user
    redirect_to user_path(user), notice: 'guestuserでログインしました。'#フラッシュメッセージ
  end
end
```
このコードではログイン後、ゲストユーザーの詳細ページへリダイレクトさせています。

# ルーティング
次に、先程作成したコントローラへ処理を行うためのルーティングを設定します。
```config/routes.rb
devise_scope :user do
    post 'users/guest_sign_in', to: 'users/sessions#guest_sign_in'
  end
```

# モデル
Userモデルに、コントローラで記述した `user = User.guest`の`guest`メソッドを定義します。
```app/models/user.rb
 def self.guest
    find_or_create_by!(name: 'guestuser' ,email: 'guest@example.com') do |user|
      user.password = SecureRandom.urlsafe_base64
      user.name = "guestuser"
    end
  end
```
::: note warn
find_or_create_byとは？
find_or_create_byは、データの検索と作成を自動的に判断して処理を行う、Railsのメソッド。
:::
::: note warn
SecureRandom.urlsafe_base64とは？
SecureRandom.urlsafe_base64は、ランダムな文字列を生成するRubyのメソッドの一種。
:::
パスワードは`SecureRandom.urlsafe_base64`でランダムな文字列にすることができます。
またnameは`"guestuser"`と固定しています。
**これで機能の部分は完成です！**

# ゲストログインボタン作成
ここからは、ゲストでログインする際のボタンを作成します。
このボタンはTopページなど、ご自身のお好みの場所に配置してください！
```app/views/homes/top.html.erb
<%= link_to 'ゲストログイン（閲覧用）', users_guest_sign_in_path, class: "btn btn-secondary btn-sm btn-block mb-3 sign_in", method: :post %>
```
:::note warn
上記コードはBootstrapにてclassを指定しています。
:::

# プロフィール編集できなくする
プロフィール編集ボタンの表示を、if文にて分岐させます。
こちらもご自身の環境に合わせて、必要なページに設定してください！
```app/views/users/info.html.erb
<% if user.name != "guestuser" %>
<div class='row'>
  <%= link_to '',edit_user_path(user),class: "btn btn-outline-secondary btn-block fas fa-user-cog edit_user_#{user.id}" %>
</div>
<% end %>
```
ユーザーの名前が`guestuser`ではない場合にはボタンを表示します。
すなわち、ユーザーの名前が`guestuser`である場合には、表示しません。

最後に、ユーザーの編集画面へのURLを直接入力された場合にはメッセージを表示してユーザー詳細画面へリダイレクトさせます。
こちらは`users_controller`に記述します。
```app/controllers/users_controller.rb
class UsersController < ApplicationController

  before_action :ensure_guest_user, only: [:edit]#before_actionでeditアクション実行前に処理を行う
  
  :
  :
  
  private

  :
  :  

  def ensure_guest_user
    @user = User.find(params[:id])
    if @user.name == "guestuser"
      redirect_to user_path(current_user) , notice: 'ゲストユーザーはプロフィール編集画面へ遷移できません。'
    end
  end  
end
```
:::note
なぜプロフィール編集をできなくする必要がある？
プロフィール編集画面へ遷移することができない仕様は、name等をあらかじめ決めておくため、あとから変更を加えられると`ログインできなくなってしまう`から。
そのため遷移ボタンの配置とURL直接入力に対しての対策が必要！
:::

# 最後に
今回は、Railsでのdeviseを活用したゲストログイン機能を実装しました。
今やどんなサイトにもログインしないで予約できたり、閲覧することができるサイトがほとんどですよね！
いちいち会員登録するのが面倒な場合もありますからね、、、
また、自身で作ったサービスを利用してもらうときも非常に便利な機能だと思います！
間違いやミス等ありましたら、ご指摘いただけると幸いです、、、！
最後までご覧いただき、ありがとうございました！