#laravel #eloquent #laravel-5.7
#laravel #красноречивый #laravel-5.7
Вопрос:
Я попытался создать функцию поиска на основе 4 запросов; categories
, location
, keyword
и sorting
. Функция поиска с 3 запросами ( location
, categories
и sorting
) работает хорошо и имеет корректный вывод.
Но проблема в том, что когда мой веб-сайт отправляет запрос с keywords
данными, выходные результаты являются только результатом только keywords
запроса, когда я пытаюсь отправить location
/ categories
запросы, выходные данные не меняются (только выходные данные только запроса ключевого слова)
Вот код, который я пишу:
public function getBy(Request $request) {
$categories = $request->all()['categories'];
$location = $request->all()['location'];
$sorting = $request->all()['sorting'];
$keyword = $request->all()['keyword'];
//--- sorting code ---
//keyword request
if ($keyword === null) {
$jobs = Job::query();
} else {
$jobs = Job::query()->where('job_title', 'LIKE', "%{$keyword}%")
->orWhere('title', 'LIKE', "%{$keyword}%")
->orWhere('description', 'LIKE', "%{$keyword}%")
->orWhereHas('users', function ($q) use ($keyword) {
$q->where('company_name', 'LIKE', "%{$keyword}%");
})->orWhereHas('categories', function ($q) use ($keyword) {
$q->where('category', 'LIKE', "%{$keyword}%");
})->orWhereJsonContains('tags', $keyword);
}
//location and categories request
if ($location === [] amp;amp; $categories === []) {
$jobs;
} elseif ($location === []) {
$jobs->whereHas('categories', function ($q) use ($categories) {
$q->whereIn('slugs', $categories);
});
} elseif ($categories === []) {
$jobs->whereHas('location', function ($q) use ($location) {
$q->whereIn('city_name', $location);
});
} else {
$jobs->whereHas('categories', function ($q) use ($categories) {
$q->whereIn('slugs', $categories);
})->whereHas('location', function ($q) use ($location) {
$q->whereIn('city_name', $location);
});
}
//return as JSON
}
Ответ №1:
Основная проблема с вашим кодом заключается в том, что вы locations
и categories
поисковый запрос снова не были настроены $jobs
. Это должно выглядеть следующим образом:
$jobs = $jobs->whereHas('categories', function ($q) use ($categories) {
$q->whereIn('slugs', $categories);
});
Это установит $jobs
переменную для включения новых условий запроса.
Я бы также предложил не проверять, являются ли $locations
или $categories
пустыми, поскольку они, если операторы для каждого из них, уже имеют дело с условием. Вот некоторый переработанный код:
public function getBy(Request $request) {
$sorting = $request->all()['sorting'];
//--- sorting code ---
//keyword request
if (! $keywords = request('keywords')) {
$jobs = Job::query();
} else {
$jobs = Job::query()->where('job_title', 'LIKE', "%{$keyword}%")
->orWhere('title', 'LIKE', "%{$keyword}%")
->orWhere('description', 'LIKE', "%{$keyword}%")
->orWhereHas('users', function ($q) use ($keyword) {
$q->where('company_name', 'LIKE', "%{$keyword}%");
})->orWhereHas('categories', function ($q) use ($keyword) {
$q->where('category', 'LIKE', "%{$keyword}%");
})->orWhereJsonContains('tags', $keyword);
}
foreach (['categories', 'locations'] as $field) {
if ($request->filled($field)) {
$jobs = $jobs->whereHas($field, function ($q) use ($field) {
$q->whereIn('slugs', request($field));
});
}
}
return $jobs->get()->toArray();
}
Здесь мы перебираем данные categories
и locations
запрашиваем данные и смотрим, являются ли данные ->filled()
(определены и не пусты). Если это так, мы выполняем запрос.
Комментарии:
1. мой API получает
categories
иlocations
в виде пустого массива[]
, если мы не вводили эти условия. Кроме того, если все мои входные данные запроса пусты, он должен показать весь запрос.2.
->filled()
справится с этим, поскольку она не будет обрабатывать, если она определена и если она пуста. Кроме того, еслиkeywords
не пройти через нее, она все равно вернет все результаты.
Ответ №2:
Попробуйте это
public function getBy(Request $request) {
$categories = $request->categories;
$location = $request->location;
$sorting = $request->sorting;
$keyword = $request->keyword;
//--- sorting code ---
$jobs = Job::query();
//keyword request
if ($keyword !== null) {
$jobs = $jobs->where('job_title', 'LIKE', "%{$keyword}%")
->orWhere('title', 'LIKE', "%{$keyword}%")
->orWhere('description', 'LIKE', "%{$keyword}%")
->orWhereHas('users', function ($q) use ($keyword) {
$q->where('company_name', 'LIKE', "%{$keyword}%");
})->orWhereHas('categories', function ($q) use ($keyword) {
$q->where('category', 'LIKE', "%{$keyword}%");
})->orWhereJsonContains('tags', $keyword);
}
//location and categories request
if ($location === []) {
$jobs = $jobs->whereHas('categories', function ($q) use ($categories) {
$q->whereIn('slugs', $categories);
});
} elseif ($categories === []) {
$jobs = $jobs->whereHas('location', function ($q) use ($location) {
$q->whereIn('city_name', $location);
});
} else {
$jobs = $jobs->whereHas('categories', function ($q) use ($categories) {
$q->whereIn('slugs', $categories);
})->whereHas('location', function ($q) use ($location) {
$q->whereIn('city_name', $location);
});
}
return $jobs->get();
}
Комментарии:
1. выдаваемый результат является только пустым массивом, если нет запроса на ввод. Если запрос на ввод не получен, должны отображаться все данные