Laravel で model をつかって and と or が混じったwhere のクエリを作る方法
Laravel で model を使って クエリを作る際、 where で and、orWhere で or のwhere 句を作成することができる。
and のみ、or のみだとなんの問題もなく簡単なのだが、and と or が混ざるととたんに意図したsql文が作れなくなる。
たとえば、
select * from hoge where a = 'a' and (b = 'b' or c = 'c');
それを単純にmodelでやると、
$ret = Hoge::where('a', 'a')->orWhere('b','b')->orWhere('c','c')->get();
でもこれで生成されるSQL文は、
select * from hoge where a = 'a' and b = 'b' or c = 'c';
日本語で言えば、aが'a'かつbが'b、又はcが'c'となってしまい意味が違う。
じゃぁどうしたらよいかというと、ちょっと見慣れない書き方が、
$model = new Hoge();
$model->where('a','a')->where(function($model) {
$model->where('b', 'b');
$model->orWhere('c', 'c');
});
model内で具体的にどんなSQL文が生成されたか確認したい場合は、
$model->toSql()
$model->getBindings()
ちなみにだが、funtion内は外の変数はスコープ外で使えないので、function外の値を使いたい場合はuseを使う。
$x = 'x'; // これをfunction内で使いたい場合
$model = new Hoge();
$model->where('a','a')->where(function($model) use($x) {
$model->where('b', 'b');
$model->orWhere('c', $x);
});
のように、use を使って渡すようにする。
以上!