0
votes

I have a Eloquent Model App\Listing which belongsTo App\Product

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

In the Listing Controller, I'm trying to get a specific listing with 2 columns (name, keywords) from the product table with it.

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);
}

I get this error:

TypeError Argument 1 passed to App\Http\Controllers\API\ListingController::App\Http\Controllers\API{closure}() must be an instance of Illuminate\Database\Eloquent\Builder, instance of Illuminate\Database\Eloquent\Relations\BelongsTo given, called in ...\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php on line 580

where line 580 is

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

When I remove the Type Declaration from the line like so

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

I get a result, but it does not include the 2 columns (name, keywords) from the product table.

{
    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
}

Why is the type declaration causing an issue and how do I get it to select the two columns from the related table?

1
Insteady of doing like return $query->select(['name','keyword']) Just do like this $query->select('name','keyword'); Without the brackets and return keywordMusawer Shah

1 Answers

2
votes

You need to include foreign_key in your case listing_id

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

this mention in laravel docs

When using this feature, you should always include the id column and any relevant foreign key columns in the list of columns you wish to retrieve.