为什么 OrWhereHas 在 Laravel 中无法正常工作
Why OrWhereHas not work correctly in Laravel
我正在创建 API 来过滤餐馆。当用户按地区查找餐厅时,我希望显示该地区的餐厅,并且餐厅将食物运送到该地区。所以,我使用了 orWhereHas.
function searchRestaurant(Request $request) {
$city = $request->input('city');
$district = $request->input('district');
$category = $request->input('category');
$fee = $request->input('fee');
$restaurants = new Restaurant();
if($district) {
$restaurants = $restaurants->where('district_id', $district)
->orWhereHas('shipdistricts', function($q) use ($district) {
$q->where('id', $district);
});
}
elseif($city && !$district) {
$restaurants = $restaurants->where('city_id', $city);
}
if($category){
$restaurants = $restaurants->whereHas('categories', function($q) use ($category) {
$q->where('id', $category);
});
}
return response()->json([
'success' => true,
'data' => $restaurants->get()->unique()->toArray()
]);
}
餐厅模特
public function shipdistricts()
{
return $this->belongsToMany(District::class, 'restaurant_districts', 'restaurant_id');
}
public function categories()
{
return $this->belongsToMany(Category::class,'restaurant_categories_relation','restaurant_id');
}
但是当我请求类别时,结果不正确。为什么?
抱歉我的英文不好!
我认为您的问题是您创建了一个新的 $restaurants = new Restaurant();
并且您正在尝试查询。请使用这个 query
:
$query = Restaurant::query();
问题很可能是您没有正确封装 orWhere()
。这将产生一个不是很明显的查询,并且仅由于 AND
优先于 OR
.
而起作用
所以您基本上必须将 district
/city
条件语句包装在 where(function ($query) { })
块中。加上 when($condition, $callback)
的良好用法,会产生如下结果:
function searchRestaurant(Request $request)
{
$city = $request->input('city');
$district = $request->input('district');
$category = $request->input('category');
$fee = $request->input('fee');
$restaurants = Restaurant::query()
->when($district, function ($query, $bool) use ($district) {
$query->where(function (query) use ($district) {
$query->where('district_id', $district)
->orWhereHas('shipdistricts', function ($query) use ($district) {
$query->where('id', $district);
});
});
})
->when($city && !$district, function ($query, $bool) use ($city) {
$query->where('city_id', $city);
})
->when($category, function ($query, $bool) use ($category) {
$query->whereHas('categories', function ($query) use ($category) {
$query->where('id', $category);
});
})
->get();
return response()->json([
'success' => true,
'data' => $restaurants->toArray(),
]);
}
您也不需要对结果使用 unique()
,因为无论如何每个 Restaurant
只能有一个实例。
我正在创建 API 来过滤餐馆。当用户按地区查找餐厅时,我希望显示该地区的餐厅,并且餐厅将食物运送到该地区。所以,我使用了 orWhereHas.
function searchRestaurant(Request $request) {
$city = $request->input('city');
$district = $request->input('district');
$category = $request->input('category');
$fee = $request->input('fee');
$restaurants = new Restaurant();
if($district) {
$restaurants = $restaurants->where('district_id', $district)
->orWhereHas('shipdistricts', function($q) use ($district) {
$q->where('id', $district);
});
}
elseif($city && !$district) {
$restaurants = $restaurants->where('city_id', $city);
}
if($category){
$restaurants = $restaurants->whereHas('categories', function($q) use ($category) {
$q->where('id', $category);
});
}
return response()->json([
'success' => true,
'data' => $restaurants->get()->unique()->toArray()
]);
}
餐厅模特
public function shipdistricts()
{
return $this->belongsToMany(District::class, 'restaurant_districts', 'restaurant_id');
}
public function categories()
{
return $this->belongsToMany(Category::class,'restaurant_categories_relation','restaurant_id');
}
但是当我请求类别时,结果不正确。为什么? 抱歉我的英文不好!
我认为您的问题是您创建了一个新的 $restaurants = new Restaurant();
并且您正在尝试查询。请使用这个 query
:
$query = Restaurant::query();
问题很可能是您没有正确封装 orWhere()
。这将产生一个不是很明显的查询,并且仅由于 AND
优先于 OR
.
所以您基本上必须将 district
/city
条件语句包装在 where(function ($query) { })
块中。加上 when($condition, $callback)
的良好用法,会产生如下结果:
function searchRestaurant(Request $request)
{
$city = $request->input('city');
$district = $request->input('district');
$category = $request->input('category');
$fee = $request->input('fee');
$restaurants = Restaurant::query()
->when($district, function ($query, $bool) use ($district) {
$query->where(function (query) use ($district) {
$query->where('district_id', $district)
->orWhereHas('shipdistricts', function ($query) use ($district) {
$query->where('id', $district);
});
});
})
->when($city && !$district, function ($query, $bool) use ($city) {
$query->where('city_id', $city);
})
->when($category, function ($query, $bool) use ($category) {
$query->whereHas('categories', function ($query) use ($category) {
$query->where('id', $category);
});
})
->get();
return response()->json([
'success' => true,
'data' => $restaurants->toArray(),
]);
}
您也不需要对结果使用 unique()
,因为无论如何每个 Restaurant
只能有一个实例。