为什么OrWhere在Laravel中无法正常工作

时间:2018-10-09 01:46:50

标签: php laravel eloquent relation

我创建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');
}

但是当我请求类别时,结果不正确。为什么? 对不起,我的英语不好!

2 个答案:

答案 0 :(得分:0)

我认为您的问题是您创建了一个新的$restaurants = new Restaurant();,并且正在尝试查询。请使用此query

$query = Restaurant::query();

答案 1 :(得分:0)

问题很可能是您没有正确封装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只能有一个实例。