murilo's avatar
Level 10

diference between load and with when paginate

hello , I have been working with laravel resource .

I have this Resorce -

class UserResorce extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            "email" => $this->email,
            "associated_users" => AssociatedUserResource::collection($this->whenLoaded('AssociatedUser'))
        ];
    }

}

If I call the resource like this -

$user   =  User::find(Auth::user()->id)->with('AssociatedUser')->paginate(5);
        return UserResorce::collection($user->items());

result -

 "email": "[email protected]",
        "associated_users": [
            {
                "id": 30,
                "email": "[email protected]",
			],
		 {
                "id": 54,
                "email": "[email protected]",
		}
	]

but if I use the load instead -

$user   =  User::find(Auth::user()->id)->load('AssociatedUser')->paginate(5);
        return UserResorce::collection($user->items());

the result will be this one -

 "email": "[email protected]"

it does not load the associated_users . why ? shold I use with when paginate ? this happens only when paginate , if I use load without pagination . it does not happen .

0 likes
3 replies
LaryAI's avatar
Level 58

The issue you're encountering is due to the way Eloquent handles eager loading with paginate and load. Let's break down the differences and why you're seeing the behavior you described.

with vs load

  • with: This method is used to eager load relationships when you are building the query. It modifies the query before it is executed.
  • load: This method is used to eager load relationships on an already executed query result. It is typically used when you have already retrieved the model(s) and want to load additional relationships.

Why with works with paginate

When you use with with paginate, the relationships are eager loaded as part of the initial query. This means that the related models are included in the query result, and they are available when you access the paginated items.

$user = User::with('AssociatedUser')->paginate(5);
return UserResource::collection($user->items());

Why load does not work with paginate

When you use load with paginate, you are trying to load relationships on a paginated result. However, paginate returns a LengthAwarePaginator instance, not a collection of models. The load method is not available on the paginator instance directly, which is why the relationships are not loaded.

$user = User::find(Auth::user()->id)->load('AssociatedUser')->paginate(5);
return UserResource::collection($user->items());

In this case, load is called on a single User instance, not on a collection of users. Therefore, it does not load the relationships for the paginated items.

Correct Approach

To achieve the desired result, you should use with when you are paginating. Here is the correct approach:

$user = User::with('AssociatedUser')->paginate(5);
return UserResource::collection($user->items());

This ensures that the AssociatedUser relationship is eager loaded for each user in the paginated result.

Summary

  • Use with when you need to eager load relationships as part of the initial query, especially when paginating.
  • load is used for eager loading relationships on already retrieved models and is not suitable for use with pagination.

By using with in your query, you ensure that the relationships are loaded correctly for each paginated item.

gych's avatar

It doesn't work with load() because load() should be used when the user collection data is already available. In your query the data isn't yet available and still needs to get fetched from the DB, so load() will not work.

with() can be used before the collection has been fetched from the DB. For queries and your use case its best to use with()

Here is an example when you could use load(), its useful when using for example: route model binding.

 public function show(User $user)
 {
	$user->load('AssociatedUser');
Snapey's avatar

im not sure what you are expecting to be paginated?

You only get one user it will never paginate.

btw, name your relationships in camel case to avoid conflicts

Please or to participate in this conversation.