Laravelで多対多リレーションを使い権限を付与・外す機能

Laravelで多対多リレーションを使った権限管理機能の実装

1612 回閲覧されました

みなさんこんにちは、jonioです。

例えば投稿サイトを作るとサイトの管理者とサイトを使うだけのユーザーがいますが管理者だけにしか表示したくない内容やページが存在します。

またサイトを運営していると特定のある人にも管理者の権限を与える必要が出てくる場合が発生したり最初から複数人で運営する場合もあります。

そこで今回は多対多リレーションを使って管理者とユーザーの権限の設定をして管理者がユーザーに管理者の権限を与えたり外す事ができる機能の実装をする方法の解説をします。

 

前提

多対多リレーションを使いますがそもそもリレーションが何かを知らないと今回の解説を理解する事ができません。

知らない方はまずは1対1リレーションを理解しましょう。

そして1対多リレーションを理解してから今回の記事を読んだ方がいいです。

 

Roleモデルの作成

まずは役割を決めるRoleモデルを作成します。

マイグレーションファイル(本日の日付_create_roles_table.php)を編集して↓にします。

そして「php artisan migrate」をするとrolesテーブルにnameカラムが作成されているのが確認できます。

 

usersテーブルの作成

多対多リレーションをするのにusersテーブルが必要なので作成します。

usersテーブルとrolesテーブルで多対多リレーションの設定をします。

usersテーブルはログイン機能を実装する際に自動的に作成されます。

ログイン機能の実装方法を知らない方は「laravel/ui」か「Breeze」で実装して下さい。

 

多対多リレーションの設定

まず多対多リレーションが何かを説明します。

例えば掲示板サイトがあったとしてユーザー(usersテーブル)に「いさじ」さんと「jonio」さんがいたとします。

サイトの権限者(rolesテーブル)に管理者と利用者がいたとします。

いさじさんは管理者と利用者の権限を持つ事ができ、反対に管理者はいさじさんとjonioさんに紐づけられます。

この様にお互いに対して複数の値を持つ時に多対多リレーションを使います。

多対多リレーションを使う時は使用するテーブルの関係を記録する為のテーブル(中間テーブルと言います)が必要になり今回はusersテーブルとrolesテーブルの関係を記録します。

1対1リレーション・1対多リレーションでは子に当たるテーブルのカラムに「親テーブル_id」カラムが必要でしたが多対多リレーションでは中間テーブルに「user_id」と「role_id」カラム(roleuserは今回使うテーブル)が必要になります。

それでは設定をしていきます。

1対多リレーションでは親モデルに「hasMany」メソッド・子モデルに「belongsTo」メソッドを使いましたが多対多リレーションではお互いのモデルに「belongsToMany」メソッドを使います。

今回はUserモデルとRoleモデルにbelongsToManyメソッドの記述をします。

そして中間テーブルの作成をします。

「–create=role_user」の「role_user」はテーブル名を指定しています。

中間テーブルを作成する時は関係を記録する2つのモデルのモデル名をアルファベット順に書く(role_userの事)というルールがあります。

中間テーブルの作成をしたらマイグレーションファイルに追加するカラムの記述をします。

「本日の日付_create_users_roles_table.php」を↓に編集します。

そしてphp artisan migrateをするとrole_userテーブルにuser_idカラムとrole_idカラムが作成されているのを確認できます。

 

Roleの初期登録

管理者・ユーザーの登録は最初だけphpMyAdminで行って管理者の権限の付与・外しは後でサイト上から行える様にします。

phpMyAdminを開きrolesテーブルを↓にします。

 

カラムの値の追加方法

やり方ですが↓の赤枠をクリックします。

そしてidカラムに「1」・nameカラムに「admin」と記入します。

記入したら「実行」をクリックします。

できたら次はidカラムに「2」・nameカラムに「user」と記入して実行します。

終わったら表示のタブをクリックして下さい。

↓になります。

 

role_userテーブルの登録

これをするに当り管理者と利用者の2人がいるのでユーザーが最低2人いないといけません。

だからユーザーが2人いないなら2人分のアカウント登録をして下さい。

usersテーブルを見ると私は↓になっています。

私は何度もユーザーを削除したのでidカラムの値が1と13になっていますが通常1と2のはずです。(idは1と2として話を進めます)

rolesテーブルのnameカラムにadminとuserを登録しましたがこれをrole_userテーブルに割り当てます。

rolesテーブルの時の様にrole_userテーブルの挿入タブを開きます。

user_idとrole_idの値を1にします。

user_idを1にする事でusersテーブルのidが1のレコードの情報を使いrole_idを1にする事でrolesテーブルのidが1のレコードの情報を使います。

同様にしてuser_idが2でrole_idが2の時も作成して下さい。

できたらrole_userテーブルは↓になります。

それでは管理者の権限を利用者にも付与する事ができる様にします。

 

権限の付与の考え方

usersテーブルとrolesテーブルに多対多リレーションを設定しましたがその際に中間テーブル(role_userテーブル)を作成しました。

role_userテーブルはusersテーブル・rolesテーブルから情報を引っ張って来る事ができます。

rolesテーブルを見ると分かるのですがrole_id=1がadmin(管理者)でrole_id=2がuser(利用者)なのが分かります。

user_id=2にrole_id=1を与える事で利用者を管理者にする事ができてrole_id=1を外す事で利用者に戻す事ができる様にします。

role_id=1を与えるのはattachメソッドを使いrole_id=1を外すのはdetachメソッドを使います。

では権限を付与・外しをする為のルーティングから設定します。

 

ルーティング(権限の付与・外し)

web.phpを↓にします。

2行目・5行目の「Route::put」のput(httpメソッド)ですが編集するからputです。

次はコントローラーです。

 

コントローラー(権限の付与・外し)

コントローラーを↓にします。

またビューを↓にします。

ビューのコードで権限を付与する表示の部分は72行目〜96行目です。

これでビューがあるページにアクセスすると見た目が↓になります。

↑の「ロール追加」を押すと管理者の権限を付与する事ができて「ロール削除」を押すと管理者の権限を外す事ができます。

それではコードの説明をします。

 

コードの説明

コントローラーの9行目と10行目ですがUser.phpのrolesメソッド・Role.phpのusersメソッドを使う為にあります。

権限に関するidはRolesテーブルのid=1がadmin(管理者)です。

↓の役割の項目がaminの所(userも)の「ロール追加」ですがビューのコードの82行目の「value=”{{$role->id}}”」であり「value=”1″」です。

コントローラーの19行目〜24行目は権限の付与をする為の記述でrole_id=1を22行目のattachメソッドで付与するので管理者になります。

21行目の「request()->input(‘role‘);」のroleはビューの82行目のname属性の値です。

この時role_userテーブルのid=2のレコードを見るとrole_idが1に変化しているはずです。(↓の赤枠はロール追加を押す前です)

また、役割の項目がadminの所(userも)の「ロール削除」がビューのコードの90行目の「value=”{{$role->id}}”」であり「value=”2″」です。

コントローラーの26行目〜30行目は権限を外す為の記述でrole_id=1を28行目のdetachメソッドで削除するので利用者になります。

ちなみにrole_id=1を付与するattachメソッド・外すdetachメソッドは多対多リレーションをしている時に使用できます。

ところでadminの項目のロール追加が{{$role->id}}が1でロール削除が{{$role->id}}が2になる理由は分かりますでしょうか?

ビューのコードの73行目の「@foreach ($roles as $role)」の「$roles」は別のコントローラーからビューに渡された変数です。

4行目の「Role::all();」でRolesテーブルの情報を全て取得しています。

@foreachでid=1のレコードの情報を表示して次にid=2のレコードの情報を表示するので1つ目(ビューの82行目)の「value=”{{$role->id}}”」が「value=”1″」になって2つ目の「value=”{{$role->id}}”」が「value=”2″」になります。

HTMLの知識がないと理解できないかもしれません。

これで管理者権限の付与・外しの機能の実装が完成です。