Closed
Description
- Laravel Version: 5.3.*
- PHP Version: 5.6 + 7.0 + 7.1
- Database Driver & Version: sqlite (3.14.0) + mysql (5.7.17 Homebrew)
Description:
There are some issues that might relate to this one, but for me they either seemed like the examples were not clear or contained domain logic that might not relate to the bug itself. See a list of such issues at the bottom.
Below I will try to explain the bug in what I see as its simplest form.
We have
- A user model
- A books model
The user has many books, but sometimes we only want 5 books, so In our User model we have the following:
/**
* Defines HasMany relationship between the user and its books
*/
public function books()
{
return $this->hasMany(\App\Books::class);
}
/**
* Limit the relationship to only include 5 results
*/
public function onlyFiveBooks()
{
return $this->books()->take(5);
}
- We have two users
- Both users have 10 books
What I expected
// Given
$users = \App\User::all();
// Act
$users->load('onlyFiveBooks');
// Assert we have two users
$users->count() == 2 // true
// Assert first user has 5 loaded books
$users->first()->getRelation('books')->count() == 5 // false
// Assert last user has 5 loaded books
$users->last()->getRelation('books')->count() == 5 // true
So I expected both users to have 5 loaded books, given the relationship defined above.
What have I tried?
// FAIL 1: Using the previously defined `books()` relationship, same as above
\App\User::with('onlyFiveBooks')->get();
// FAIL 2: Still only loads 5 books to the last of the two users
\App\User::with(['books' => function($query) {
$query->take(5);
}])->get();
// FAIL 3: Still only loads 5 books to the last of the two users
$users = \App\User::all();
$users->load(['books' => function($query) {
$query->take(5);
}]);
// SUCCESS: Being explicit (and maybe redundant) does produce the correct outcome
$users = \App\User::all();
$users->each(function($user) {
$user->load('onlyFiveBooks');
});
// Assert first user has 5 loaded books
$users->first()->getRelation('books')->count() == 5 // true
// Assert last user has 5 loaded books
$users->last()->getRelation('books')->count() == 5 // true
In the wild
I've setup a project with a failing test to illustrate this bug.
git clone https://github.com/jstoone/laravel \
-b bug-in-a-limited-eager-load-example \
jstoone-laravel-example
cd jstoone-laravel-example
composer install
cp .env.example .env
phpunit
Somewhat similar issues
Metadata
Metadata
Assignees
Labels
No labels