Отношения Laravel - есть ли несколько * ненужных * вызовов базы данных?

У меня есть 2 модели: Post и User, где у каждой Post есть одна User, а у каждой User много Post.

Пользователь.php:

// User.php

public function posts()
{
    return $this->hasMany(Post::class);
}

Пост.php:

// Post.php

public function user()
{
    return $this->hasOne(User::class);
}

Загружаю пост через свой PostsController:

// PostsController.php

public function show($id)
{
    $post = Post::find($id);

    return view('posts.show', compact('post'));
}

В представлении я звоню как сообщению, которое я загрузил в , так и пользователю, имеющему отношение к сообщению. Я делаю несколько вызовов пользовательскому объекту:

// views/posts/show.blade.php

<h1>{{ $post->title }}</h1>
<p>{{ $post->user->name }}</p>
<p>{{ $post->user->email }}</p>

Будут ли эти 2 обращения к ресурсу $post->user выполнять 2 обращения к базе данных?

Как отношения Eloquent работают на бэкэнде? Отношение всегда возвращает весь объект user, когда я получаю объект post, или оно лениво получает данные user?

Меня беспокоит размещение моей базы данных у поставщика, который взимает плату на основе данных, переданных из базы данных (GCP), и я не понимаю, как отношения Eloquent будут вызывать базу данных.


person Jacob    schedule 19.10.2017    source источник
comment
Из документов: динамические свойства загружаются отложенно , что означает, что они будут загружать данные о своих отношениях только тогда, когда вы действительно получите к ним доступ.   -  person ljubadr    schedule 20.10.2017
comment
И он будет запущен только один раз для $post->user   -  person ljubadr    schedule 20.10.2017
comment
Я чувствую, что этот вопрос слишком широк. То, о чем вы спрашиваете, описано в документах и ​​в исходном коде.   -  person fubar    schedule 20.10.2017


Ответы (1)


Laravel предоставляет функцию под названием Eager Loading, которая позволяет загружать модель и любые отношения путем оптимизации запросов:

Post::with('user')->find($id);

Нетерпеливая загрузка работает и со многими отношениями. Следующее также приведет к двум запросам, независимо от количества сообщений, которые есть у пользователя:

User::with('posts')->find($id);

Это загрузит пользовательскую модель сущности Post, чтобы для доступа к ней не требовался второй запрос. Вы можете узнать больше об ускоренной загрузке и других улучшениях производительности в документах.

person samrap    schedule 19.10.2017
comment
Нетерпеливая загрузка выполнит 2 запроса: ... К счастью, мы можем использовать нетерпеливую загрузку, чтобы сократить эту операцию до 2 запросов. При запросе вы можете указать, какие отношения должны быть загружены с помощью метода with ... - person ljubadr; 20.10.2017
comment
Я бы немного обновил ответ, чтобы охватить вопрос Будут ли эти 2 обращения к ресурсу $post-›user делать 2 обращения к базе данных? . Посмотрите на мои комментарии под вопросом и расширьте его;) - person ljubadr; 20.10.2017
comment
Любые дополнительные вопросы подробно рассматриваются в документации. Я могу скопировать и вставить документы или просто дать ссылку на них, как у меня уже есть :) - person samrap; 20.10.2017
comment
Это был буквально вопрос Будут ли эти 2 звонка.... В его примере есть 2 запроса: 1 для постов и 1 для пользователя. Ему было интересно, выполняются ли 3 запроса и как это работает? - person ljubadr; 20.10.2017