Laravel пытается выбрать столбцы принадлежностей к отношениям

У меня есть красноречивая модель App\Listing, которая belongsTo App\Product

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

В контроллере листинга я пытаюсь получить конкретный листинг с двумя столбцами (name, keywords) из таблицы продуктов с ним.

public function readListing(Request $request, $listingId)
{
    $query = Listing::query();
    $item = $query->with(['product' => function (Builder $query) {
        return $query->select(['name', 'keywords']);
    }])->findOrFail($listingId);
    return response()->json($item->toArray(), 200);
}

Я получаю такую ​​ошибку:

Аргумент TypeError 1, переданный в App \ Http \ Controllers \ API \ ListingController :: App \ Http \ Controllers \ API {closure} (), должен быть экземпляром Illuminate \ Database \ Eloquent \ Builder, экземпляром Illuminate \ Database \ Eloquent \ Relations \ BelongsTo given, вызывается в ... \ vendor \ laravel \ framework \ src \ Illuminate \ Database \ Eloquent \ Builder.php в строке 580

где строка 580

$item = $query->with(['product' => function (Builder $query) {

Когда я удаляю объявление типа из строки вот так

$item = $query->with(['product' => function ($query) {

Я получаю результат, но он не включает 2 столбца (name, keywords) из таблицы товаров.

{
    id: 1,
    product_id: 1,
    listing_price: 10,
    actual_price: 5,
    in_stock: 1,
    listing_date: null,
    delisting_date: null,
    created_at: "2021-02-24T12:33:48.000000Z",
    updated_at: "2021-02-24T13:45:25.000000Z",
    deleted_at: null,
    category: "Fruits",
    category_id: 2,
    description: "Rem laudantium aut",
    image_urls: [
        ".../storage/products/February2021/CF3nzhmc0RXevSWdOJcd.jpg",
        ".../storage/products/February2021/oBtXf5kBjkAyrazuFDyu.jpg",
        ".../storage/products/February2021/GfpaGxSoGLA2FBqGrcDX.jpg"
    ],
    image_medium_urls: [
        ".../storage/products/February2021/CF3nzhmc0RXevSWdOJcd-medium.jpg",
        ".../storage/products/February2021/oBtXf5kBjkAyrazuFDyu-medium.jpg",
        ".../storage/products/February2021/GfpaGxSoGLA2FBqGrcDX-medium.jpg"
    ],
    image_small_urls: [
        ".../storage/products/February2021/CF3nzhmc0RXevSWdOJcd-small.jpg",
        ".../storage/products/February2021/oBtXf5kBjkAyrazuFDyu-small.jpg",
        ".../storage/products/February2021/GfpaGxSoGLA2FBqGrcDX-small.jpg"
    ],
    thumbnail_url: ".../storage/products/February2021/CF3nzhmc0RXevSWdOJcd-small.jpg",
    product: null
}

Почему объявление типа вызывает проблему и как заставить его выбрать два столбца из связанной таблицы?


person Samik Sengupta    schedule 01.03.2021    source источник
comment
Вместо того, чтобы делать что-то подобное return $query->select(['name','keyword']) Просто делайте это $query->select('name','keyword'); Без скобок и ключевого слова return   -  person Musawer Shah    schedule 01.03.2021


Ответы (1)


Вам нужно указать foreign_key в вашем случае listing_id

    $query = Listing::with(['product' => function ($query) {
    // add listing_id
        return $query->select(['listing_id', 'name', 'keywords']);
    }])
        ->findOrFail($listingId);

это упоминание в документации laravel

При использовании этой функции вы всегда должны включать столбец id и все соответствующие столбцы внешнего ключа в список столбцов, которые вы хотите получить.

person Aslam    schedule 01.03.2021
comment
Хотя в таблице продуктов нет столбца listing_id, он работает, когда я добавляю столбец его первичного ключа и другой зависимый столбец, например: return $query->select(['id', 'name', 'keywords', 'category_id']); - person Samik Sengupta; 01.03.2021