【Laravel5.8】リレーション先のカラムも含めてレコードを絞り込みたい(whereHas/whereDoesntHave)
例えば以下のようなテーブルがあるとします。
マイグレーション
Jobsテーブル
Schema::create('jobs', function (Blueprint $table) { $table->bigIncrements('id'); $table->text('title'); $table->longText('content'); $table->timestamps();
Subscribesテーブル
Schema::create('subscribes', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('job_id'); ★ $table->integer('status'); //1 ->応募・ 2->決定・3->納品完了・4->検収完了の4つの状態 ★ $table->timestamps(); $table->foreign('job_id') ★ ->references('id') ->on('jobs');
Jobテーブルが親、Subscribesテーブルが子というリレーション。
Model.php
もちろんModelには以下のようなModel内メソッドを作成します。
Job.php
public function subscribesToJob() {
return $this->hasMany('App\Subscribe','job_id');
}
リレーション先のカラムも含めてレコードを絞り込みたい
例えばContorollerで、
「Subscribesテーブルカラムのstatusが『1』のJobテーブルレコードだけを抽出したい」
というときがあるはずです。
そのような際に使用できるのは、
- whereHas
- whereDoesntHave
というメソッド。
実際に以下のようにして
「Subscribesテーブルカラムのstatusが『1』のJobテーブルレコードだけを抽出したい」
という要望を叶えることができました。
Controller
$my_jobs = Job::where('user_id',Auth::user()->id) ->whereDoesntHave('subscribesToJob', function($query){$query->where('status', 2);}) ->whereDoesntHave('subscribesToJob', function($query){$query->where('status', 3);}) ->whereDoesntHave('subscribesToJob', function($query){$query->where('status', 4);})->get();
「whereDoesntHave」や「whereHas」はどうやら、複数条件を一気に付け加えられないっぽく、並べることしかできませんでした。(方法はあるかも)
また上記では、
Job::where('user_id',Auth::user()->id)
と最初に付け加え、ログインユーザーが持つJobテーブルレコードだけを先に抽出していますのでご注意ください。