eager-load-pivot-relations
eager-load-pivot-relations copied to clipboard
Error when paginating after eagerLoading
When chaining a ->paginate() after eager loading the following is thrown:
Call to a member function newCollection() on null in ajcastro/eager-load-pivot-relations/src/EagerLoadPivotBuilder.php on line 78
My scenario is pretty much standard (as the README shows):
users:
- id
- name
car_models:
- id
- name
colors:
- id
- name
user_has_car_model:
- id
- user_id
- car_model_id
- color_id
Yet, for some reason, we can run:
User::find(1)->cars()->with(['pivot.color'])->get();
but can't do the following
User::find(1)->cars()->with(['pivot.color'])->paginate()
Doing some extra research it turns out on the result to head($pivots)
inside EagerLoadPivotBuilder::eagerLoadPivotRelations()
is an array with a null value element (array:1 [0 => null]
) instead of containing the pivot itself.
@Jesuso Didn't happen to me, I re-created your example and it works on me.
This is what I did:
https://github.com/ajcastro/eager-load-pivot-relations-examples/blob/master/cars/routes/web.php,
using a fresh install of latest laravel(5.8.19) and the latest version of this package (v0.2.1).
@ajcastro I have just got this issue with laravel/framework:7.28.4 and ajcastro/eager-load-pivot-relations:v0.2.2
Did some debugging with the following:
protected function eagerLoadPivotRelations($models, $pivotAccessor)
{
dump($pivotAccessor);
dump($pivots);
$pivots = Arr::pluck($models, $pivotAccessor);
dump($pivots);
dump(head($pivots));
$pivots = head($pivots)->newCollection($pivots);
$pivots->load($this->getPivotEagerLoadRelations($pivotAccessor));
}
and got the following results when calling ->paginate(15)
"pivot"
array:20 [
0 => App\Models\User ...
1 => App\Models\User ...
2 => App\Models\User ...
3 => App\Models\User ...
4 => App\Models\User ...
5 => App\Models\User ...
6 => App\Models\User ...
7 => App\Models\User ...
8 => App\Models\User ...
9 => App\Models\User ...
10 => App\Models\User ...
11 => App\Models\User ...
12 => App\Models\User ...
13 => App\Models\User ...
14 => App\Models\User ...
array:15 [
0 => null
1 => null
2 => null
3 => null
4 => null
5 => null
6 => null
7 => null
8 => null
9 => null
10 => null
11 => null
12 => null
13 => null
14 => null
]
null
and the correct but unpaginated results when just calling ->get()
"pivot"
array:20 [
0 => App\Models\User ...
1 => App\Models\User ...
2 => App\Models\User ...
3 => App\Models\User ...
4 => App\Models\User ...
5 => App\Models\User ...
6 => App\Models\User ...
7 => App\Models\User ...
8 => App\Models\User ...
9 => App\Models\User ...
10 => App\Models\User ...
11 => App\Models\User ...
12 => App\Models\User ...
13 => App\Models\User ...
14 => App\Models\User ...
array:20 [
0 => App\Models\User ...
1 => App\Models\User ...
2 => App\Models\User ...
3 => App\Models\User ...
4 => App\Models\User ...
5 => App\Models\User ...
6 => App\Models\User ...
7 => App\Models\User ...
8 => App\Models\User ...
9 => App\Models\User ...
10 => App\Models\User ...
11 => App\Models\User ...
12 => App\Models\User ...
13 => App\Models\User ...
14 => App\Models\User ...
App\Models\User ...
After a little more investigating I found how to replicate.
Here is your example from above:
User::with(['cars.pivot.color'])->paginate();
I can replicate with the following
User::find(1)->cars()->with(['pivot.color'])->paginate();
Anyone gotten a fix for this? :(
Same issue
Hey @ajcastro ,
First let me thank you for the great package. It saved me a lot of headaches.
Second, I did encounter the same issue mentioned above. This happens whenever you try to load relationships on a relationship function directly and then paginate such as @fennik showed above (but it works if you use ->get()
or ->first()
).
I don't really know why, but maybe it is related to the way the paginate method works:
/**
* Get a paginator for the "select" statement.
*
* @param int|null $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
$this->query->addSelect($this->shouldSelect($columns));
return tap($this->query->paginate($perPage, $columns, $pageName, $page), function ($paginator) {
$this->hydratePivotRelation($paginator->items());
});
}
https://github.com/laravel/framework/blob/7e0e0d0c3dec9f0978d4e616681d86c5749c0b00/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php#L829-L845
The hydratePivotRelation
may cause the $pivots = Arr::pluck($models, $pivotAccessor);
variable to be null (https://github.com/ajcastro/eager-load-pivot-relations/blob/55ffe9423d538aa5a0d35ddbb335556f6fe3fdfa/src/EagerLoadPivotBuilder.php#L79).
Unfortunately, I have not enough knowledge to really understand what is going wrong... But I hope those leads might help :)
Have a nice day
Reopening this so I can take a look later
Thanks a lot 🙏🏾
@ajcastro did you have a chance to take a look into this?