Как фильтровать отношения модели laravel, где, если связь пуста/пуста, она не должна показывать объект

#laravel #eloquent #model

Вопрос:

Я не знаю, что делать, чтобы исправить эту проблему, с которой я сталкиваюсь в laravel, где результаты отношений моделей возвращают пустые/пустые поля отношений, когда я хочу, чтобы они отображали только «животных» с данными при выполнении вызова GET со строкой поиска. Например, в ответе ниже в поле «favorite_animals» я хочу, чтобы в этом массиве отображался только объект «животные» с данными.

Это конечная точка localhost/api/v1/списки/2?поиск=honeybadger

     "name": "titleTwo",
        "description": "list two",
        "favorite_animals": [
            {
                "animals": null
            },
            {
                "animals": {
                    "id": 1,
                    "name": "HoneyBadger",
                    "description": "dgaf",
                    "created_at": "2021-07-30T22:49:36.000000Z",
                    "updated_at": "2021-07-30T22:49:36.000000Z"
                }
            },
            {
                "animals": null
            }
        ]
 

Ниже приведен блок кода в контроллере, который запрашивает данные модели:

 $list = UsersAnimalList::with(['favoriteAnimals.animals' => function($query) use($request){
$query->where('name', 'like', $request->input('search'));}])->get();
 

Ниже приведены отношения модели:

Модель: UserAnimalList

 public function favoriteAnimals(){
return $this->hasMany(UsersFavoriteAnimals::class, 'list_id', 'id');}
 

Модель: Любимые пользователями животные

 public function animals(){
return $this->hasOne(Animals::class, "id", "animals_id");}
 

Другая модель, но не имеет метода взаимосвязи с ними: Животные

Я пробовал использовать has (), но это вернуло пустой ответ. Я попытался изменить отношение с hasMany() на hasOne (), оно изменилось только с отображения пустого массива на нуль;

Я также пытался использовать where() в попытке отфильтровать поле отношения, сгенерированное null «животные», но я получаю сообщение об ошибке, в котором говорится, что поле не существует.

Ответ №1:

Есть 2 вещи, которые вы можете сделать:

  1. используйте встроенный toArray() метод laravel для возврата значений внутри массива, а затем используйте функцию php array_filter() для удаления пустых значений
  2. Вы можете создать collection и использовать встроенную filter() функцию laravel для удаления пустых значений из коллекции данных

Ответ №2:

Вы также можете фильтровать модели на основе наличия отношений:

 $list = UsersAnimalList::with(['favoriteAnimals.animals' => function($query) use($request) {
    $query->where('name', 'like', $request->input('search'));
}])->has('favoriteAnimals.animals')->get();
 

Это задокументировано здесь

Комментарии:

1. Я попытался использовать has (), аналогичный тому, что вы отправили, и whereHas (), но пустые/пустые поля все еще отображались. Основываясь на моем тестовом использовании, я, к сожалению, смог заставить его фильтровать только по базовой модели отношений UsersAnimalList. В то время как вызов внутренней связи модели животных, которую я хотел отфильтровать, остался нетронутым, показывая пустые/пустые поля.