[英]Conditional wherehas with Laravel Eloquent
I have one similar ( area
) value in two tables one
and two
and these two tables has relation with main table master
. 我在两个表
one
和two
有一个相似的( area
)值,这两个表与主表master
表有关。 At a time, the master
table will be having data in one relation only and the other one will be null
. 一次,
master
表将仅具有一种关系的数据,而另一种将为null
。
With this architecture, I have a search page where user can search any values related to these tables and the search fields are placed with AND
condition. 使用这种体系结构,我有一个搜索页面,用户可以在其中搜索与这些表相关的任何值,并且将搜索字段放置为
AND
条件。
Here, if user enters some value for area
I need to check the area value exists in any one of the tables ( one
or two
) without breaking the AND
condition. 在这里,如果用户输入
area
某个值,我需要检查任何一个表( one
或two
)中存在的面积值,而不会破坏AND
条件。 Tried the below code but it is breaking AND
rule and considering OR
. 尝试了以下代码,但它违反了
AND
规则并考虑了OR
。 Any suggestions to fix? 有什么建议可以解决吗?
$result = Master::where(function ($query) use ($request) {
if ($request->filter == true) {
$query->where('user_id', Auth::user()->id);
}
// other conditions here
if (!empty($request->area_from) && !empty($request->area_to)) {
$query->whereHas('one', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
$query->orWhereHas('two', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
}
// other conditions here
})->with(['one', 'two'])->paginate($request->item);
You are wrapping all of your where statements in brackets. 您将所有where语句包装在方括号中。 I think what you want to do is pull your first part of the query out of the where clause so that you can easily wrap the
whereHas
part in brackets. 我认为您想要做的是将查询的第一部分从where子句中拉出,以便您可以轻松地将
whereHas
部分包装在方括号中。
// Initialise the model
$query = new Master;
// Start building the query
if ($request->filter == true) {
$query->where('user_id', Auth::user()->id);
}
if (!empty($request->area_from) && !empty($request->area_to)) {
// Wrap these in brackets so we don't interfare with the previous where
$query->where(function($query2) use ($request) {
$query2->whereHas('one', function ($query3) use ($request) {
$query3->whereBetween('area', [$request->area_from, $request->area_to]);
});
$query2->orWhereHas('two', function ($query3) use ($request) {
$query3->whereBetween('area', [$request->area_from, $request->area_to]);
});
}
}
$query->with(['one', 'two'])->paginate($request->item);
You can create a merged relationship refer this link 您可以创建合并关系, 请参考此链接
public function mergedOneAndTwo($value)
{
// There two calls return collections
// as defined in relations.
$onedata= $this->one;
$twodata= $this->two;
// Merge collections and return single collection.
return $onedata->merge($twodata);
}
and use whereHas('mergedOneAndTwo')
并使用
whereHas('mergedOneAndTwo')
Using a closer where and making the conditional inside may work fine 在更近的地方使用闭环并使其有条件
$master = Master::with('one')->with('two');
$result = $master->where(function($subQuery)
{
$subQuery->whereHas('one', function ( $query ) {
$query->whereBetween('area', [$request->area_from, $request->area_to] ); //assuming $request->area_from, $request->area_to is range of value
})
->orWhereHas('two', function ( $query ) {
$query->whereBetween('area', [$request->area_from, $request->area_to] );
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.