🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Eloquent

Eloquentとは、PHPフレームワークのLaravelに最初から含まれているORM(Object-relational mapping:オブジェクト関係マッピング)です。

Q&A

解決済

1回答

3050閲覧

Laravelでユーザーのロールで絞り込んで取得したい

kiwsr

総合スコア6

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Eloquent

Eloquentとは、PHPフレームワークのLaravelに最初から含まれているORM(Object-relational mapping:オブジェクト関係マッピング)です。

0グッド

0クリップ

投稿2019/12/19 11:29

編集2019/12/19 12:13

Laravel(6.5.1)で、laravel-permission を使って権限管理をしております。

ひとりのuserにつき1つ以上のroleを割り当てています。

rolesテーブルのnameカラムはr1r100のように権限の高いものほど数字が小さくなるようにしています。

Userモデルに以下のようにリレーションを定義しています。

php

1public function roles() { 2 return $this->morphToMany(\Spatie\Permission\Models\Role::class, 'model', 'model_has_roles', 'model_id', 'role_id', 'id', 'id'); 3}

ユーザーの一覧を取得する場合、すべてのユーザーの場合は以下のように取得できました。

php

1$users = App\User::with('roles')->all();

例えば**r20以上(つまりr1r20のいずれか)の権限を持ったユーザーの一覧を取得する**必要があり、いろいろ調べて試しているのですがうまくいかず詰まってしまいました。
うまく絞り込んで取得するにはどのような方法があるでしょうか?
アドバイスをいただければ幸いです。

※一旦全件取得してから以下のように絞り込むことはできたのですが、おそらくベストな方法ではないと思います。

php

1$users = $users->map(function($item){ 2 $item->roles->filter(function($item){ 3 return $item->min('name'); 4 }); 5 return $item; 6});

※最終的にはページネーションやソートなども必要なのですが、ひとまず現時点では忘れています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

leftjoinしてあげてwhereInあたりで指定したらどうでしょうか?

php

1$users = App\User::with('roles') 2 ->leftjoin('roles' , 'user.role_id', '=','roles.id') 3 ->whereIn("roles.name", ["r1","r2" ..... ,"r20"]) //※ whereInの中身は略してます。 4 ->get(); 5

下記は質問の件とは別件となりますが
ロール権限の比較用のnameカラムで、r1~r100と文字列なのが気になります。

権限レベルを別のカラムに、int型で管理すれば比較的に楽に絞り込みしやすい気がしますが
何か意図があるのでしょうか?

投稿2019/12/20 01:43

編集2019/12/20 01:55
e-suzuno

総合スコア74

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kiwsr

2019/12/20 10:17 編集

早速ご回答いただきありがとうございます! アドバイスいただいた方法で試してみたところ、中間テーブルをはさんでいるためかうまくいかなかったので、参考にさせていただきつつ下記のように修正したところ絞り込んでの取得ができた・・・かと思ったのですが、 $users = App\User::with('roles') ->leftjoin('model_has_roles' , 'users.id', '=','model_has_roles.model_id') ->where('model_has_roles.model_type', 'App\User') ->leftjoin('roles' , 'model_has_roles.role_id', '=','roles.id') ->whereIn("roles.name", ["r1","r2" ..... ,"r20"]) //※ whereInの中身は略してます。 ->get(); 返ってきた$usersのデータをよく見てみると、意図したユーザーの一覧にはなっているのですが、`id(ユーザーID)`が`rolesのidに`、`name(ユーザー名)`が`rolesのname`になってる等、同名のカラムがごっちゃになっているようなのです。 LaravelもMySqlも基本的なことしかわからずまた詰まってしまっています。またアドバイスをいただければ幸いです。 ロール権限の比較用カラムが文字列なのは、laravel-permissionのデフォルトのテーブルをそのまま使っているためで、深い意味はありません。 int型の別カラムで管理するとよいとのご指摘ありがとうございます。最終的にそのようにしたいと思います。
e-suzuno

2019/12/22 09:56 編集

selectを指定するのをうっかりしてました。 $users = App\User::with('roles') ->select("users.*") ->leftjoin('roles' , 'users.role_id', '=','roles.id') ->whereIn("roles.name", ["r1","r2" ..... ,"r20"]) ->get(); 上記のようにすれば$usersはusersテーブルの情報だけになると思います。
kiwsr

2019/12/23 09:51

うまくいきました! ありがとうございます! 引き続きアドバイスいただいたロール権限のint型での管理など、いろいろやってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問