0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails6 Deviseを使ったユーザー退会処理方法

Last updated at Posted at 2023-05-06

はじめに

今回はユーザー退会処理の機能、退会後同じメールアドレスとパスワードではログインできないようにする方法を記載します。

開発環境、前提条件

  • AWS Cloud9
  • Ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
  • Rails 6.1.7.3
  • Deviseのインストールが完了していて、ユーザーの新規登録やログインができる状態。

Userテーブル定義

is_deletedカラムを作成し、デフォルトをfalseにしておきます。
退会ユーザーのis_deletedをtrueにすることで退会ユーザーのデータは残したまま、退会しているかどうかを区別できるようにします。

カラム名 カラム説明 データ型 デフォルト
ID ユーザーID integer
name ユーザー名 string
is_deleted 削除フラグ datetime FALASE
created_at 登録日 datetime NOW
updated_at 更新日 boolean NOW

users.controllerの編集

hideアクションを作成します。
@user.update(is_deleted: true)で、@userのis_deletedカラムをtrueにupdateします。
reset_sessionで、ユーザーをログアウトさせます。
redirect_to root_pathで、ログアウト後ルートパスに飛ばします。
indexアクションを作成します。
退会済みのユーザーは、is_deletedカラムがtrueに設定されているため、このページに表示されません。

app/controllers/users_controller.rb

   def index
     @users = User.where(is_deleted: false) #users/indexページでは、is_deletedカラムがfalseのユーザーのみが表示されます
   end

   def hide
    @user = User.find(params[:id])
    @user.update(is_deleted: true) #is_deletedカラムにフラグを立てる(defaultはfalse)
    reset_session
    flash[:notice] = "ありがとうございました。またのご利用を心よりお待ちしております。"
    redirect_to root_path
  end

しかしこのままでは直接URLに"user/:id"を入力するとユーザーの詳細情報を確認することができてしまいます。
そこでusers.controllerに追記しましょう。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :check_user_status,  only:[:show]
.
.
.

private

  def check_user_status
    user = User.find(params[:id])
    if user.is_deleted
      redirect_to root_path
  end
end
end

この記述ではshowアクションが呼び出される前にcheck_user_statusメソッドが呼び出され、指定されたユーザーのis_deletedカラムがtrueかどうかチェックし、退会済みの場合はroot_pathにリダイレクトされます。
こうすることで直接URLを叩いても退会済みのユーザの詳細ページを閲覧することはできません。

ルーティングの作成

hideアクションのルーティングを作成します。
as: 'users_hide'で、showアクションと間違われないようURL名を指定します。

config/routes.rb
Rails.application.routes.draw do

  devise_for :users

    resources :users do
    member do
      delete :hide, as: 'users_hide'
    end
 end


end

退会ボタンの作成

ユーザー編集ページ(users/:id/edit.html.erb)

if user_signed_in? && @user.id == current_user.idで、ユーザーがログインしていて且つログインユーザーであれば退会ボタンを表示するようにしています。
"data-confirm" => "本当に退会しますか?"で退会ボタンクリック時にアラートが出るようにしています。

app/views/users/show.html

<div class="form_group">
    <% if user_signed_in? && @user.id == current_user.id %>
    <%= link_to "退会", users_hide_user_path(current_user), method: :delete, "data-confirm" => "本当に退会しますか??", class: "btn btn-outline-danger" %>
    <% end %>
</div>

退会ユーザーはログインできなくする

user.rb

ログインする時に退会済み(is_deleted==true)のユーザーを弾くためのメソッドを作成します。
super && (self.is_deleted == false)で、userのis_deletedがfalseならtrueを返すようにしています。

app/models/user.rb
 #退会ユーザーはログインできなくする
  def actuve_for_authentication?
    super && (self.is_deleted == false)
  end

sessions_controller.rb

if (@user.valid_password?(params[:user][:password])で、入力されたパスワードが正しいことを確認しています。
(@user.active_for_authentication? == false))で、@userのactive_for_authentication?メソッドがfalseであるかどうかを確認しています。
・上記の2点が当てはまれば、ログインページにリダイレクトし、エラーメッセージを表示するようにしています。

app/controllers/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController

  before_action :reject_user, only: [:create]

  protected

  def reject_user
    @user = User.find_by(email: params[:user][:email].downcase)
    if @user
      if (@user.valid_password?(params[:user][:password]) && (@user.active_for_authentication? == false))
        flash[:error] = "退会済みです。"
        redirect_to new_user_session_path
      end
    else
      flash[:error] = "必須項目を入力してください。"
    end
  end
end

便利なフラッシュメッセージの記述

通常フラッシュメッセージの表示は<%= flash[:error] %>とすると思いますが毎回ページごとに記述するよりも簡単な方法があります。

application.html.erbファイルに以下のコードを追加して、フラッシュメッセージが表示されるようにします。

app/application.html.erb
<% flash.each do |key, value| %>
  <div class="alert alert-<%= key %>">
    <%= value %>
  </div>
<% end %>

このコードは、コントローラーで設定されたフラッシュメッセージをループで処理し、それぞれのメッセージを表示します。keyには:notice、:alertなどのフラッシュの種類が、valueにはメッセージの内容が入ります。

BootStrapをインストール済みの場合はフラッシュメッセージの配置を帰ることも可能です。以下例

app/application.html.erb
<% flash.each do |key, value| %>
  <div class="alert alert-<%= key %> alert-dismissible fade show position-fixed fixed-top w-25 ml-auto mt-3 mr-3" role="alert">
    <%= value %>
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
<% end %>

このコードでは、position-fixed, fixed-top, w-25, ml-auto, mt-3, mr-3 クラスを使用して、フラッシュメッセージを画面右上に配置しています。

以上で実装完了です。コメント、いいねお待ちしてます!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?