👋

Rails|退会処理済み会員のログインを阻止する方法|devise

2023/08/18に公開

追記

後々壁にぶち当たったので、新しくこちらの記事を追記しました。
https://zenn.dev/airiin/articles/023fc13679e607

開発環境

ruby 3.1.2p20
Rails 6.1.7.4
Cloud9

前提

deviseを導入済み
Memberモデル、Adminモデルを作成済み
テーブル内容はこちらの記事の通り
https://zenn.dev/airiin/articles/4691b219877e67

退会処理済み会員のログインを阻止する方法

ECサイトを作成しています。顧客は当ECサイトで会員登録や退会処理をすることができます。
退会処理を行ったユーザーアカウントの情報を使ってログインしようとした際に、ログインを阻止し、新規登録画面にリダイレクトする方法を解説します。

membersテーブル

membersテーブルには、is_deletedというカラムを付与済みです。これはboolean値で、デフォルトはfalseです。

つまり、memberが退会する時、is_deletedの値をtrueに変更します。(destroyでデータを削除するわけではありません。)

schema.rb
...
  create_table "members", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "family_name", null: false
    t.string "first_name", null: false
    t.string "family_name_kana", null: false
    t.string "first_name_kana", null: false
    t.string "post_code", null: false
    t.string "address", null: false
    t.string "telephone_number", null: false
    t.boolean "is_deleted", default: false, null: false
    t.index ["email"], name: "index_members_on_email", unique: true
    t.index ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true
  end
  ...

memberが「退会する」ボタンを押した時

memberが「退会する」ボタンを押した時、
1️⃣ そのmemberの is_deleted の値を trueに変更する。
2️⃣ ログアウトし、トップ画面に戻る
という動きをします。

members_controller.rb
  def quit
    @member = current_member
    @member.update(is_deleted: true)
    reset_session
    redirect_to root_path
  end

reset_session でセッションのデータを削除(ログアウト)します。

退会済みのmemberがログインしようとした時

退会処理を実行したmemberがログインしようとした時、
1️⃣ ログイン画面で入力された emailを持つ memberが存在するかどうか確認
2️⃣ 存在する場合、ログイン画面で入力されたパスワードと、
  そのmemberのパスワードが一致しているかどうか確認
3️⃣ 一致する場合、そのmemberのis_deletedの値を確認
4️⃣ trueだった場合、退会済みということなので、新規登録画面にリダイレクトさせる
  falseだった場合、そのmemberは有効なので、ログインさせる
という流れで処理を行います。

sessions_controller.rb
class Public::SessionsController < Devise::SessionsController
  before_action :is_deleted?, only: [:create]

  protected
  
  def is_deleted?
      @member = Member.find_by(email: params[:member][:email])
      return if !@member
      if @member.valid_password?(params[:member][:password])
        if @member.is_deleted == true
          redirect_to new_member_registration_path
        else
          return
        end
      end
  end
  
end

@member = Member.find_by(email: params[:member][:email])
ログイン画面で入力されたメールアドレスを持つ memberを @memberに代入します。

return if !@member
@memberが存在しない場合、そこで処理は終了です。

if @member.valid_password?(params[:member][:password])
ログイン画面で入力されたパスワードがそのmemberのパスワードであるかどうかを認証します。valid_password?メソッドはdeviseが用意しているメソッドです。

@member.is_deleted == true
memberのis_deletedカラムの値を確認しています。

redirect_to new_member_registration_path
新規登録画面へリダイレクトさせています。

return
退会済みでない場合、このメソッドは不要なので、このメソッドの処理を終了させています。

Discussion