リレーション先のテーブルに条件をつけて取得するケース(whereHas)

2018/10/12

Laravelで開発をしている中で、リレーション先のテーブルのカラムに対して検索をかけたいことが発生しました。

これが結構はまってしまいました。

今回は「リレーション先のテーブルに対して検索をかけたい」ケースついてエントリーします。

 

状況

データベース

部署テーブル:depts
従業員テーブル:employees

【 ポイント 】
部署テーブルにある stairs カラムはどの階にあるかという意味です。
今回はこのカラムがキーポイントになります。

 
モデル

class Dept extends Model
{
  //hasMany設定
  public function employees()
  {
  return $this->hasMany('App\Employee');
  }
}
class Employee extends Model
{
  //belongsTo設定
  public function dept()
  {
  return $this->belongsTo('App\Dept');
  }
}

 

やりたいこと

1階で働いている人を抽出したい。

=(リレーション先のテーブル(depts)にある stairs カラムで検索したい。)

 

問題

リレーション先のテーブル(depts)にあるカラム(stairs)で検索をかけるとします。

  public function select(){
    $employees = \App\Employee::where('stairs','1')->get();
  return view('employee.list')->with('employees',$employees);
  }

 
実行結果

エラーになりました。

stairsカラムがないというメッセージが表示されています。

Eloquentモデルでリレーションをしてもリレーション先のテーブルは検索対象にはならないのです。

 

解決策

whereHasを利用します。

【 構文 】
whereHas($relation, Closure $callback)
リレーション先のテーブルに検索条件を詳細に指定する際に使用するメソッド。
クロ―ジャーの中にリレーション先のカラムの条件を指定してあげます。
public function select(){
    $employees = \App\Employee::whereHas('Dept', function($q){
    $q->where('stairs', 1);
})->get();

 

【 解説 】
Eloquentモデルの結合を使うのではなく、クエリービルダーのJoin句でもOKです。

        $employees = \App\Employee::select()
                    ->join('depts','depts.id','=','employees.dept_id')
                    ->where('stairs',1)
                    ->get();

 
実行結果

リレーション先のテーブルにおける条件検索に関しては以上です。

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-実践知識