5

I want to limit related records from

$categories = Category::with('exams')->get();

this will get me exams from all categories but what i would like is to get 5 exams from one category and for each category.

Category Model

public function Exams() {

    return $this->hasMany('Exam');
}

Exam Model

public function category () {

return $this->belongsTo('Category');

}

I have tried couple of things but couldnt get it to work

First what i found is something like this

$categories = Category::with(['exams' => function($exams){

   $exams->limit(5);

  }])->get();

But the problem with this is it will only get me 5 records from all categories. Also i have tried to add limit to Category model

public function Exams() {

return $this->hasMany('Exam')->limit(5);
}

But this doesnt do anything and returns as tough it didnt have limit 5.

So is there a way i could do this with Eloquent or should i simply load everything (would like to pass on that) and use break with foreach?

miken32
  • 42,008
  • 16
  • 111
  • 154
MePo
  • 1,044
  • 2
  • 23
  • 48

2 Answers2

6

There is no way to do this using Eloquent's eager loading. The options you have are:

  1. Fetch categories with all examps and take only 5 exams for each of them:

    $categories = Category::with('exams')->get()->map(function($category) {
      $category->exams = $category->exams->take(5);
      return $category;
    });
    

It should be ok, as long as you do not have too much exam data in your database - "too much" will vary between projects, just best try and see if it's fast enough for you.

  1. Fetch only categories and then fetch 5 exams for each of them with $category->exams. This will result in more queries being executed - one additional query per fetched category.
jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
  • I have tried with First solution (with map) but it gave me (var_dumped) `array (size=4) 0 => null 1 => null 2 => null 3 => null`, strange as it should work (tried to make it work but it gives null no matter what, it just iterates trough). – MePo Jul 30 '15 at 05:46
  • But i will go with your Second solution, and thank you for mentioning map that might comes in handy later. – MePo Jul 30 '15 at 06:22
  • 1
    Sorry, there was a lame bug in the example, I forgot to return from map(), so everything was set to null. Just fixed it – jedrzej.kurylo Jul 30 '15 at 07:02
  • I figured that out 5min later (when i poste it) but went with 2nd approach so thanks again – MePo Jul 30 '15 at 08:54
0

I just insert small logic inside it which is working for me.

$categories = Category::with('exams');

Step 1: I count the records which are coming in response

$totalRecordCount = $categories->count()

Step 2: Pass total count inside the with function

$categories->with([
  'exams' => function($query) use($totalRecordCount){
      $query->take(5*$totalRecordCount);
  }
])

Step 3: Now you can retrieve the result as per requirement

$categories->get();
Durga
  • 49
  • 4