Laravel 5.7でコンテンツ配信サービスの開発を行っており、Relation関係で困っているのでご相談させてください。
・Userが複数のLicenseを持つ(1:n関係)
・Licenseは複数のContentを持つ(n:n関係)
という要件で、モデルにリレーションメソッドを作成しました。
PHP
1class User extends Model { 2 /** 3 * このユーザーが持つライセンス取得を行う 4 */ 5 public function licenses() { 6 return $this->hasMany(Licenses::class); 7 } 8} 9 10class Lincese extends Model { 11 /** 12 * このライセンスに割り当たっているコンテンツ取得を行う 13 */ 14 public function contents() { 15 return $this->belongsToMany(Content::class); 16 } 17 18 /** 19 * 有効なライセンスのフィルタリングを行う 20 */ 21 public function scopeActive($query) { 22 return $query->where('active', true); 23 } 24} 25 26class Content extends Model { 27 /** 28 * 公開済みコンテンツのフィルタリングを行う 29 */ 30 public function scopeAvailable($query) { 31 return $query->where('available', true); 32 } 33}
上記の例において、ログイン中のユーザーが参照できるコンテンツ一覧を表示する画面を作る際、
EagerLoadingで視聴可能なContentの一覧を取得したいと思いました。
PHP
1class User extends Model { 2 /****** 省略 *****/ 3 4 /** 5 * この利用者の視聴可能なコンテンツ一覧の取得(をしたい) 6 */ 7 pubic function viewableContents() { 8 return $this->licenses() 9 ->active() 10 ->with(['content'=>function($query){ 11 $query->available(); 12 }]); 13 } 14} 15 16class MainController extends Controller { 17 /****** 省略 *****/ 18 19 /** 20 * ログイン中の利用者の視聴可能なコンテンツ一覧を表示 21 */ 22 public function showLibrary() { 23 $contents = Auth::user()->viewableContents() 24 ->orderByDesc('contents.created_at'); 25 return view('user.library', compact($contents)); 26 } 27}
上記のUser#viewableContents()を実行すると「視聴可能なContentを持ち」、「有効なLicense」の一覧は取得できるのですが、Content の一覧にはならず、ライセンスの一覧が取得されてしまいます。
呼び出し元のController側で、viewableContents()の結果を基にLicenseの結果をループで回しながら、Contentの一覧を作成してもいいのですが、並び替えやページングの処理を自分で実装しなければならなくなってしまいます。
MainController#showLibrary() で取得した$contentsに対して、paginate等も実行したいです。
上記のように、EagerLoadingで取得してきた子テーブルのデータのみを一覧取得するようなクエリビルダの書き方があれば教えて欲しいです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/19 16:20