Дисциплины - Ресурсно-компонентное программирование

База данных - Модели - Содержит много hasMany

Один пользователь может содержать множество телефонов. Тогда следует использовать связь hasMany(). Другими примерами данного отношения «один ко многим» является статья в блоге, которая имеет «много» комментариев или мама, имеющая детей. Мы можем смоделировать это отношение таким образом:

 class User extends Model{
  public function phones()
  {
    return $this->hasMany('Phone');
  }
 }

Теперь мы можем получить все телефоны пользователя с помощью динамического свойства:

$phones = User::find(1)->phones;

В этом случае, мы получили массив телефонов, и для просмотра всех телефонов, нужно пройтись по элементам массива.

 foreach($phones as $one){
  echo $one->body;
  echo '\n';
 }

Если нужно добавить ограничения на получаемые телефоны, можно вызвать метод phones() и продолжить добавлять условия:

$phone = User::find(1)->phones()->where('title', '=', 'foo')->first();

Теперь мы получили один телефон, который сразу можно вывести на экран:

 $phone->body

Рассмотрим еще один пример, который выявит недостатки связи hasMany. Предположим, у нас есть модель Book и модель Author. Book принадлежит (связь belongsTo) Author. И наоборот, Author содержит (связь hasMany) множество Book.

Определение связи в модели Book:

class Book extends Model {
    public function author()
{
        return $this->belongsTo('Author');
    }
}

Получить все названия книг можно следующим образом:

foreach (Book::all() as $book)
{
    echo $book->name;
}

Мы обошлись всего одним заросом. Даже если будет 100 книг, это всё-равно один запрос:

SELECT * FROM books

Однако, если к выводу названия книги добавим автора:

foreach (Book::all() as $book)
{
    echo $book->name;
    echo $book->author->name;
}

То, получаем 101 запрос. Первым запросом получаем все книги, а потом в цикле делаем запрос на получение автора книги.

SELECT * FROM books;
SELECT * FROM authors WHERE id = 1;
SELECT * FROM authors WHERE id = 2;
SELECT * FROM authors WHERE id = 3;
...

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

Активная загрузка

Акнивная загрузка подразумевает подключение связующей модели с помощью метода with.

foreach (Book::with('author')->get() as $book)
{
    echo $book->author->name;
}

Таким образом будут выполнены всего два запроса:

 SELECT * FROM books;
 SELECT * FROM authors WHERE id IN(1,2,3);

Конечно, вы можете загрузить несколько отношений одновременно:

$books = Book::with('author', 'publisher')->get();

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

Количество комментариев: 0

Для того, чтобы оставить коментарий необходимо зарегистрироваться
20421 БГУИР
30421 БГУИР