Почему OrWhere не работает правильно в Laravel - PullRequest
0 голосов
/ 09 октября 2018

Я создал 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 голосов
/ 09 октября 2018

Скорее всего, проблема в том, что вы неправильно инкапсулируете 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 может быть только один экземплярв любом случае.

0 голосов
/ 09 октября 2018

Я считаю, что ваша проблема в том, что вы создали новый $restaurants = new Restaurant(); и пытаетесь выполнить запрос.Пожалуйста, используйте это query:

$query = Restaurant::query();
...