2

I have a table named categories and a table named courses. These tables have one-to-many relation, it means each course belongs to one category and each category has many courses. Now, I want to get five categories (order is not important yet) and 4 courses for each of these categories. I tried some of the solutions on stackoverflow and around the web but none of them worked! One of them (the below code) gets 4 courses for first item only!

$result = Category::with(['courses' => function ($query) {
    $query->take(4);
})->take(5)->get();

I solved this problem with for loop, but I wonder if laravel has its solution for this. I'll be appreciated for your answers. :)

Ashkan
  • 47
  • 1
  • 8

1 Answers1

1

there is a laravel package specialized in this called Eloquent Eager Limit:

after installing it:

composer require staudenmeir/eloquent-eager-limit:"^1.0"

you should use it inside the models that would apply limited eager loading:

class Category extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
 // ........
}

class Course
extends Model
{

use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
 // ........
}

now this query will get the result you want:

   $result = Category::with(['courses' => function ($query) {
    $query->take(4);
})->take(5)->get();
OMR
  • 11,736
  • 5
  • 20
  • 35
  • 1
    Yes! this is what I want. I really expected laravel to have this feature!! Thank you. :) – Ashkan Jun 07 '21 at 14:48
  • 2
    Wow, super interesting. I would have expected `Model::has('relations', '>=', 4)->with(['relations' => function ($query){ $query->limit(4); }])->limit(5)->get();` (similar to the deleted answers below) to return 5 `Model` instances, each with 4 `Relation` instances, but only the first Model has 4, the rest have 0. Great find on this question and solution! – Tim Lewis Jun 07 '21 at 15:17