開発環境
macbook air(M1)
rails 6.0.3
ruby 3.0.1
状況
- 一般ユーザーと管理ユーザーが存在するrailsアプリケーション
- gem等使用せず開発する
- 管理ユーザが一人もいなくなってしまわないように、更新・削除の制御をしたい
- users tableのカラムはname, email, password_digest, adminの構成
- adminはboolean型で管理
コード例
データベースに登録されている最後の管理者が自身の管理権限を更新、削除出来ないよう、modelにコールバックを設定する。
before_update :admin_cannot_update
before_destroy :admin_cannot_delete
private
def admin_cannot_update
throw :abort if User.exists?(admin: true) && self.saved_change_to_admin == [true, false]
end
def admin_cannot_delete
throw :abort if User.exists?(admin: true) && self.admin == true
end
コード例解説
コールバック
before_update :メソッド…データが更新される前にメソッドの内容を実行
before_delete :メソッド…データが削除される前にメソッドの内容を実行
メソッド
admin_cannot_update
if User.exists?(admin: true)
…もしusersテーブルのadminカラムにtrue(管理者)で登録されているデータが1つだけで、
&& self.saved_change_to_admin == [true, false]
…かつ変更を加えようとしているレコードのadminカラムがtrueからfalseに変更されようとしている場合(最後の管理者がtrueからfalseに帰られようとしている場合)
saved_change_to_attributeメソッドについてはこちらをご参照ください
throw :abort
処理を無視する
admin_cannot_delete
if User.exists?(admin: true)
…もしusersテーブルのadminカラムにtrue(管理者)で登録されているデータが1つだけで、
&& self.admin == true
…かつ変更を加えようとしているレコードのadminカラムがtrueの場合
throw :abort
処理を無視する