24

Стосунки один до багатьох у Ларавел (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
        
    

Якщо у вас виникли складнощі з розумінням або реалізацією ми завжди готові допомогти вам для цього, зв'яжіться з нами зручним для вас способом.

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