31

Отношения один ко многим в Ларавел (Laravel) объяснение и нетерпеливая загрузка (eager loading), как использовать?

Как использовать отношения один ко многим в Ларавел (Laravel) и нетерпеливую загрузку (eager loading)

Связь один ко многим и многие к одному наиболее часто используемая в веб программировании.

Начнем с простого примера этой связи. Например у одного человека есть множество банковских карт и каждая из этих карт принадлежит только этому человеку или у пользователя есть множество комментариев и каждый этот комментарий принадлежит именно этому пользователю.

Как использовать отношения один ко многим в Ларавел (Laravel) и нетерпеливую загрузку (eager loading) 2

Связь один ко многим и многие к одному в Ларавел (Laravel) реализуется следующим способом.

Изначально следует определится будете ли вы придерживается правил именований таблиц и ключей Ларавел (Laravel).

Это руководство соответствует всем правилам именований для упрощения понимания примеров и описывает преимущества нетерпеливой загрузки (eager loading). Ознакомится с требованиями к таблицам баз данных можно в документации данного фреймворка.

Используем простой пример пользователей и их постов.

Создадим две таблицы: Users, Posts.

Как использовать отношения один ко многим в Ларавел (Laravel) и нетерпеливую загрузку (eager loading) 3

Далее определим две модели: User и Post - (имена в единственном числе).

В модели User:

        
public function posts() {

                //--- Имя функции во мнж. числе
                //--- Ссылаемся на мнж. Связь.

// Ссылаемся из родительской на дочернюю

return $this->hasMany(Post::class);

}
        

В модели Post:

        
public function user() {    
                // ---   в единственном числе 
                // ---   Ссылаемся на одн. Связь.

 // Ссылаемся из дочерней на родительскую

 return $this->belongsTo(User::class);  
}

Нетерпеливая загрузка (Eager Loading) предпочтительна

Запрос к базе данных происходит только один раз, загружая данные и их связи. И при последующем обращении к свойствам и их отношениям внутри приложения, база данных больше не затрагивается. Таким образом экономя огромный ресурс, это особенно заметно на больших проектах.

Определение нетерпеливой загрузки (Eager Loading) выполняется с помощью вызова функции with() в которую передаются имена функций указанных в моделях, строкой.

Выборка данных с помощью нетерпеливой загрузки (Eager Loading).

Пример выборки пользователя с (id 1) и всех его постов:

        
User::with('posts')->where('id', 1)->get();
        

Рассмотрим другой пример и представим, что у постов пользователя есть комментарии. Сделаем теперь выборку всех постов и комментариев для того же пользователя.

        
User::with('posts.comments')->where('id', 1)->get(); 
        

Как узнать кто автор поста с (id 1)? Для этого воспользуемся отношением (многие-к-одному).

        
Post::with('user')->where('id', 1)->get();
        

Пойдем дальше и определим комментарий с (id 1) к каким постам принадлежит и кто авторы этих постов (если таковые есть):

        
Comment::with('post.user')->where('id', 1)->get();
        

Как получить результат всех отношений разных направлений как для одного так и для всех пользователей?

Как использовать отношения один ко многим в Ларавел (Laravel) и нетерпеливую загрузку (eager loading) 10

Изменим предыдущий пример и выберем теперь пользователя с (id 1) и все его посты, а так же комментарии к ним это связи (one to many), но мы хотим так же получить все заголовки этих постов это связь (one to one), как это сделать? Просто перечислите отношения, разделив их запятой в функции with().

        
$users =

User::with(['posts.comments', 'posts.description'])->where('id', 1)

->get();
        

Можно делать огромные цепи связей и легко получать доступ к любой таблице понятным и простым способом используя преимущества нетерпеливой загрузки (Eager Loading) при этом получая оптимизированные запросы к базе данных. Соответственно предварительно добавив в модель функции: hasMany, hasOne и belongsTo столько сколько необходимо. Главное правильно указывать последовательность функций.

Ленивая загрузка (Lazy Load) не рекомендуеться

Используется по умолчанию при обращении к свойствам и их отношениям внутри приложения каждый раз будет запрашивать базу данных. К примеру есть 50 комментариев и на каждой итерации цикла произойдет обращение к базе данных всего 51.

        
@foreach ($users as $user)

   $user->comments
   
@endforeach
        

Если у вас возникли сложности с пониманием или реализацией мы всегда готовы помочь вам для этого свяжитесь с нами удобным для вас способом.

Автор: Юрий Лысенко