Reputation: 143
I have a one-to-many relationship in my model. Basically a Category
and a Product
. A product can only have one category but a category can have many products. The code below works:
return Category::select('id', 'name')->whereIn('id', $categories)->with('products')->get();
It returns with a product key and within that the product columns in the database, but when I use eager loading it just returns an empty set:
return Category::select('id', 'name')->whereIn('id', $categories)->with(['products' => function($query){
$query->limit(5);
}])->get();
I've also tried adding the return keyword like this return $query->limit(5);
but still no luck.
I have also tried specifying columns like this:
return Category::select('id', 'name')->whereIn('id', $categories)->with('products:id,name')->get();
But it still returns an empty dataset.
Since I'm building an API, this is what the JSON data looks like:
[
{
"id": 161,
"name": "Health & Personal Care",
"products": []
},
{
"id": 256,
"name": "Makeup & Fragrances",
"products": []
},
]
My table structure:
categories (there's no product_id column, since it's one to many)
+----+------+
| id | name |
+----+------+
| | |
+----+------+
| | |
+----+------+
| | |
+----+------+
product
+----+------+-------+-------------+
| id | name | price | category_id |
+----+------+-------+-------------+
| | | | |
+----+------+-------+-------------+
| | | | |
+----+------+-------+-------------+
| | | | |
+----+------+-------+-------------+
My category model is declared like this:
public function products()
{
return $this->hasMany(Product::class);
}
and the product model is:
public function category()
{
return $this->belongsTo(Category::class);
}
Upvotes: 1
Views: 810
Reputation: 12218
you are trying to limit the loaded relation, not the query, you can do this using eloquent-eager-limit
install it:
composer require staudenmeir/eloquent-eager-limit:"^1.0"
then in Category Model:
class Category extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
.....
public function products()
{
return $this->hasMany(Product::class, 'product_id');
}
public function lastFiveProducts()
{
return $this->hasMany(Product::class, 'product_id')
->latest()->limit(5);
}
}
and in Product:
class Product extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
......
}
now this query will get the expected results:
return Category::select('id', 'name')->whereIn('id', $categories)->with(['products' => function($query){
$query->limit(5);
}])->get();
or using the new relation:
return Category::select('id', 'name')->whereIn('id', $categories)->with(['lastFiveProducts'])->get();
also note when you use ->with('products:id,name')
loading a relation with specific columns, you always should load the foreing key ->with('products:id,name,category_id')
Upvotes: 1