Rails 退会機能実装
はじめに
現在チーム開発中、プログラミング2ヶ月目の初学者です🔰
deviseを使用して退会機能を実装しましたので、メモとして残します!
論理削除と物理削除
まず、退会機能の論理削除と物理削除ってなに??
⭐️論理削除とは
テーブルに削除フラグを項目として用意し、そのTRUE/FALSEで削除をされたかどうか管理する方法
メリット
- データの復旧が可能
- 削除したデータも検索などで参照できる
デメリット
- データが実質減らないので、ストレージを圧迫する可能性がある
⭐️物理削除とは
SQLでDELETE文を発行してレコードを削除すること
メリット
- レコードが削除される為、ストレージを圧迫しにくい
- 論理削除と比べると実装が容易(destroyアクションの活用)
デメリット
- 簡単に復元したり、削除されたデータを参照できない
退会用カラムの追加
退会管理用のカラムの追加を行う!
rails g migration AddIsDeletedToCustomers is_deleted:boolean
このカラムにデフォルト値(false)を設定し、登録した直後は false が設定されるようにする🙆🏻♀️
create_table "customers", force: :cascade do |t|
t.boolean "is_deleted", default: false, null: false
end
ルーティング
論理削除用に任意の名前のルーティングを作成。(アクション名が被ってはいけない!)
Rails.application.routes.draw do
# 顧客用
devise_for :customers
:
# 会員側のルーティング設定
scope module: :public do
root to: 'homes#top'
# customers
get '/customers/mypage' => 'customers#show'
get '/customers/information/edit' => 'customers#edit'
patch '/customers/information' => 'customers#update'
+ # 退会確認画面
+ get '/customers/check' => 'customers#check'
+ # 論理削除用のルーティング
+ patch '/customers/withdraw' => 'customers#withdraw'
:
end
退会画面の作成
退会画面を表示させて、本当に退会するか確認してもらう。
<h1>本当に退会しますか?</h1>
<p>
退会すると、会員登録情報や<br>
これまでの購入履歴が閲覧できなくなります。<br>
退会する場合は、「退会する」をクリックしてください。
</p>
<%= link_to "退会しない", customers_mypage_path, :class => "btn btn-primary ms-3" %>
<%= link_to "退会する", customers_withdraw_path, method: :patch, :class => "btn btn-danger ms-3", data: { confirm: "本当に退会しますか?" } %>
data: { confilm: "本当に退会しますか?" } の記述により、退会ボタンを押した時に確認ボックスが出現する!
2度の操作を挟むことにより、手違いによる退会を防いでいる💪🏻
コントローラー
-
@customer.update(is_deleted: true)
= current_customerが持つ、is_deletedカラムをtrueにupdateして、退会状態にする。 -
reset_session
= セッション情報を全て削除 -
redirect_to root_path
= 退会後トップ画面に遷移
Sessionとは
- ページ遷移しても以前入力した情報を保持することができる機能
- sessionは明示的に削除されるまで消えない
class Public::CustomersController < ApplicationController
def withdraw
@customer = Customer.find(current_customer.id)
# is_deletedカラムをtrueに変更することにより削除フラグを立てる
@customer.update(is_deleted: true)
reset_session
flash[:notice] = "退会処理を実行いたしました"
redirect_to root_path
end
end
モデルに制約をかける
ログイン時に退会済みのユーザーが同じアカウントでログイン出来ないようにする。
class Customer < ApplicationRecord
# is_deletedがfalseならtrueを返すようにしている
def active_for_authentication?
super && (is_deleted == false)
end
end
session_controller.rb
退会処理を行った会員が、同じアカウントでログイン出来ないようにする。
同じアカウントでログインしようとすると、新規会員登録画面へ遷移します!
-
@customer = Customer.find_by(email: params[:customer][:email])
= ログイン時に入力されたメールアドレスに対応するユーザーが存在するか探す。 -
@customer.valid_password?(params[:customer][:password])
= 入力されたパスワードが正しいことを確認。 -
(@customer.is_deleted == true)
= @customerのactive_for_authentication?メソッドがfalseであるかどうか
class Public::SessionsController < Devise::SessionsController
before_action :reject_customer, only: [:create]
protected
def reject_end_user
@end_user = EndUser.find_by(email: params[:end_user][:email])
if @end_user
if @end_user.valid_password?(params[:end_user][:password]) && (@end_user.is_deleted == true)
flash[:notice] = "退会済みです。再度ご登録をしてご利用ください"
redirect_to new_end_user_registration_path
else
flash[:notice] = "項目を入力してください"
end
else
flash[:notice] = "該当するユーザーが見つかりません"
end
end
end
-
find_byメソッド
ID をもとに検索を行う find メソッドに対し、ID 以外のカラムからも検索を行い
該当する1件を取得するメソッド
今回の場合は、Customer モデルから入力された email を検索し、該当する 1 件を取得する用途で使用
-
valid_password?メソッド
特定のアカウントのパスワードと入力されたパスワードが一致しているかを
確認するためのDevise が用意しているメソッド
今回の場合は、find_by メソッドで特定したアカウントのパスワードとログイン画面で入力されたパスワードが一致しているかを確認する用途で使用
🌱参考にさせていただいた記事
https://qiita.com/Wata16/items/9e05596afb671e540365
終わった後に書いているのと確認が充分にできていないので
もしかしたら記述もれや間違いがあるかもしれないです🥲
Discussion
さやかさん!大変だとおもうけどファイティン!🥹👍🏻
めちゃくちゃ時間に追われている、、😂ありがとう!!あいりちゃんも面接ファイト💪🏻