#php #laravel #laravel-7
#php #laravel #laravel-7
Вопрос:
В настоящее время я пытаюсь внедрить службу регистрации проблем, когда задача завершена, дата может быть введена в столбец «завершено», для которого у меня есть CRUD.
Идея заключается в том, что пользователь выбирает из выпадающего списка со следующими значениями:
- 0 — Скрыть завершенные задачи
- 1 — Показывать только завершенные задачи
- 2 — Показывать как завершенные, так и выполняемые задачи
Мой код контроллера:
public function all(Request $request){
$result = IssueLog::where('deleted', '=', null)
->when($request->sys, function ($q) use($request){
$q->where('system', $request->sys);
})
->when($request->sub, function ($qw) use($request){
$qw->where('sub_system', $request->sub);
})
->when($request->complete, function ($qr) use($request){
switch ($request->complete) {
case 0:
return $qr->whereNull('completed');
case 1:
return $qr->whereNotNull('completed');
case 2:
return $qr->whereNull('completed')
->orWhereNotNull('completed');
default:
return $qr->whereNull('completed');
}
})
->orderByRaw('updated_at DESC NULLS LAST')
->get();
return $result;
}
Результаты из случая 1 возвращаются, как и ожидалось, однако случаи 0 и 2 кажутся точно такими же, где даты, которые не являются нулевыми, проходят в случае 0, где их не должно быть. Я также убедился, что перед запуском функции в запрос передается правильное значение.
Комментарии:
1.
when($request->complete, ...
может быть,0
это рассматривается как ложное значение, а когда не вводится?2. Похоже, проблема может заключаться в значении 0, которое разрешается как false…
3.
where('deleted', '=', null)
вероятно, должно бытьwhereNull('deleted')
тоже.4. как я могу изменить это, чтобы не считать его ложным? лучший способ просто начать с 1 вместо 0?
5.
case 2
вероятно, также должно быть простоreturn $qr;
— вам не нужно проверять, является ли оно null или not null. Это всегда будет соответствовать всему.
Ответ №1:
Поскольку у вас есть предложение по умолчанию в вашем внутреннем switch
элементе управления, я предполагаю, что вам нужен запасной вариант на случай, если completed
он не указан в запросе.
Использование when()
означает, что вы будете условно применять определенный запрос. Первый аргумент определяет, следует ли его использовать или нет — на основе «правдивости» аргумента. 0
это ложное значение, поэтому оно не будет выполняться, когда это так (посмотрите официальное руководство по логическим значениям).
Вместо этого мы можем применить where()
предложение с закрытием. Мы также можем очистить его и повторно использовать те же результаты для разных условий (например, по умолчанию и case 0
). Например case 2
, вы хотите вернуть как те, которые завершены, так и те, которые не завершены, поэтому вместо применения whereNull('completed')->orWhereNotNull('completed')
вы можете просто вернуть сам запрос.
Я также заменил where('deleted', '=', null)
на whereNull('deleted')
, поскольку это правильный подход для проверки, является ли столбец NULL
.
public function all(Request $request)
{
$result = IssueLog::whereNull('deleted')
->when($request->sys, function ($q) use ($request) {
return $q->where('system', $request->sys);
})
->when($request->sub, function ($qw) use ($request) {
return $qw->where('sub_system', $request->sub);
})
->where(function($query) use ($request) {
switch ($request->complete) {
case 1:
return $query->whereNotNull('completed');
case 2:
return $query;
case 0:
default:
return $query->whereNull('completed');
}
})
->orderByRaw('updated_at DESC NULLS LAST')
->get();
return $result;
}
Вам также следует рассмотреть возможность использования $request->has("sys")
(или чего-то подобного !empty($request->sys)
) вместо предоставления фактического значения запроса первому аргументу ваших when()
методов. Эти две функции возвращают логическое значение и являются более явными, чем передача всего значения.