skip to Main Content

When Laravel Eloquent calls a relation property that indicates the original model of the relation destination from a certain model, it issues a re-query and returns the original model.
Is there a way to return the original model without issuing a requery?

In posts->first()->author, laravel execute query select * from "users" where "users"."id" = ? limit 1.

I hope no execute query, and author returns $user.

https://laravelplayground.com/#/snippets/348b2dea-ac2a-423b-86c5-6ec17593546e

code image

2

Answers


  1. You are doing this

    Route::get('/', function() {
        $u = User::with(['posts'])->first();
    
        ddd($u->posts->first()->author->name);
    });
    

    You get the user posts correctly and it gives the posts collection in terms of relations, and your eager loading as well so correct but then you try are trying to access the author name as well on the first collection of posts and not eager loading.
    Try this instead.

    Route::get('/', function () {
        $user = User::with('posts.author')->whereId(1)->first();
        foreach ($user->posts as $post) {
            dump($post->author->name);
        }
    });
    

    This will Eager load all the posts with the responding authors and it will not create N + 1 queries.

    Login or Signup to reply.
  2. without making a db query to load the author, when the author is the already loaded user, you can set the relation yourself

    Route::get('/', function() {
        $user = User::with(['posts'])->first();
        $user->posts->each(function (Post $post) use ($user) {
            $post->setRelation('author',  $user);
        });
    });
    

    now each post will have a author relation set on the current user.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search