Как исключить столбец отношения из массива результатов коллекции — нетерпеливая загрузка

#php #model #laravel-8 #eager-loading

Вопрос:

Я пытаюсь понять, как исключить/скрыть столбец отношений в массиве результатов сбора данных для загрузки

У меня есть 2 модели, и вот отношения

Product.php

 class Product extends Model
    {
        public function Category()
        {
            return $this->belongsTo(Category::class);
        }
    }
 

Category.php

 class Category extends Model
    {
        public function Product()
        {
            return $this->hasMany(Product::class);
        }
    }
 

Поля таблицы

Категория: удостоверение личности, имя

Товар: идентификатор, название, идентификатор категории

итак, вот мой вопрос

 $result = Product::leftJoin('product_tags', 'product.id', 'product_tags.product_id')
        ->with(['category' => function ($q) {
            $q->selectRaw('id,name as category_name');
        }])
        ->select('product.id', 'product.name','product.category_id',DB::raw('group_concat(DISTINCT(product_tags.product_tag)) as product_tag'))
        ->groupBy('product_tags.product_id')
        ->paginate($limit)
        ->toArray();
 

вот ответ

 {
    "id": 50,
    "name": "three",
    "category_id": 2, // this field I need to exclude from result array
    "product_tag": "123,3",
    "category": {
        "id": 2,
        "category_name": "Azo"
    }
}
 

ниже приведен ответ, который я исключаю

 {
    "id": 50,
    "name": "three",
    "product_tag": "123,3",
    "category": {
        "id": 2,
        "category_name": "Azo"
    }
}
 

Я пробовал делать это так:

1.

 $result['data'] = collect($result['data'])->except(['category_id']);
 
  1. $результат[‘данные’] = сбор($результат)->преобразование(функция($i) {
    сбросить($i->идентификатор категории);
    вернуть $i;
    });

даже я пытался использовать except() вспомогательную функцию, но, похоже, все усилия бессмысленны

ПРИМЕЧАНИЕ: Я знаю, что могу установить защищенные свойства в модели ($hidden или $visible), я могу захотеть использовать ее в разных контекстах и использовать разбиение на страницы по умолчанию в laravel.

Возможно ли это и каким — либо образом сделать это?

Большое спасибо.

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

1. Если вы этого не хотите, просто не указывайте в методе выбора. ->select('product.id', 'product.name',DB::raw...

2. @BadPiggie Я пробовал, что если я не укажу в методе select, то это даст мне объект нулевой категории -> category:null

3. laracasts.com/discuss/channels/eloquent/…

Ответ №1:

С первой попытки у каждого ребенка будет category_id свой, а не основной массив.

 collect($result)->map(function($item) {
    return collect($item)->except('category_id');
})->toArray();
 

На втором вы используете toArray() в своем основном массиве, поэтому для снятия category_id настроек вам нужно использовать []

 unset($i['category_id']);
 

PS: Я вижу paginate() , что это результат этого, результат конечной точки? В этом случае вы можете проверить ресурс API.

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

1. Эй, второй unset($i['category_id']); решает проблему — Спасибо

Ответ №2:

Вы можете использовать makeHidden() метод.

 $paginator = Product::leftJoin('product_tags', 'product.id', 'product_tags.product_id')
        ->with(['category' => function ($q) {
            $q->selectRaw('id,name as category_name');
        }])
        ->select('product.id', 'product.name','product.category_id',DB::raw('group_concat(DISTINCT(product_tags.product_tag)) as product_tag'))
        ->groupBy('product_tags.product_id')
        ->paginate($limit);

$result = $paginator->makeHidden(['product.category_id'])->toArray();