Laravel Eloquent загружает ненулевые даты, когда запрашиваются нулевые даты

#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() методов. Эти две функции возвращают логическое значение и являются более явными, чем передача всего значения.