Laravel и отношения в примерах

В этой записи я максимально просто и кратко опишу структуру отношений для Laravel с использованием Eloquent.

Предполагается, что вы корректно указали внешние ключи для связей ваших моделей.

Один к одному

Представим две таблицы, где у водителя может быть одна машина:

Driver
id integer
name string
car_id integer

Car
id integer
name string

Для получения машины, которая есть у владельца, используется отношение:

$this->hasOne('App\Car');

Для получения водителя определённой машины используется обратное отношение:

$this->belongsTo('App\Driver');

Один ко многим

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

$this->hasMany('App\Car');

Для получения водителя определённой машины используется обратное отношение (belongsTo), которое описано выше.

Многие ко многим

Представим, что связь водителей и машин определены следующими таблицами:

Driver
id integer
name string

Car
id integer
name string

CarDriver
driver_id integer
car_id integer

Чтобы получить машины определённого водителя используем отношение:

$this->belongsToMany('App\Car');

Для получения водителя определённой машины используется обратное отношение:

$this->belongsToMany('App\Driver');

Ко многим через

Представим, что связь групп, водителей и машин определены следующими таблицами:

Group
id integer
name string

Driver
id integer
name string
group_id integer

Car
id integer
name string
driver_id integer

Для получения машин определённой группы используется следующее отношение:

$this->hasManyThrough('App\Car', 'App\Driver');

К одному через

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

Garage
id integer
name string

Driver
id integer
name string
garage_id integer

Car
id integer
name string
driver_id integer

Для получения машины из определённого гаража используется следующее отношение:

$this->hasOneThrough('App\Car', 'App\Driver');

Один к одному (полиморфные отношения)

Представим, что связь документов для водителя и машины определены следующими таблицами:

Driver
id integer
name string

Car
id integer
name string

Document
id integer
name string
documentable_id - integer (id водителя или машины)
documentable_type - string (имя класса родительской модели)

Для получения всех водителей и машин (моделей), имеющих документы, используется следующее отношение:

public function documentable()
{
    return $this->morphTo();
}

Для получения одного документа водителя или машины (для каждой модели в отдельности) используется следующее отношение:

$this->morphOne('App\Document', 'documentable');

Один ко многим (полиморфные отношения)

Представим, что связь документов для водителя и машины определены теми же таблицами, что и выше.

Для получения документов водителя или машины (для каждой модели в отдельности) используется следующее отношение:

$this->morphMany('App\Document', 'documentable');

Многие ко многим (полиморфные отношения)

Представим, что связь документов для водителя и машины определены следующими таблицами:

Driver
id integer
name string

Car
id integer
name string

Document
id integer
name string

Documentables
document_id integer
documentable_id - integer (id водителя или машины)
documentable_type - string (имя класса родительской модели)

Для получения документов водителя или машины (для каждой модели в отдельности) используется следующее отношение:

$this->morphToMany('App\Document', 'documentable');

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

Для получения водителя:

$this->morphedByMany('App\Driver', 'documentable');

Для получения машины:

$this->morphedByMany('App\Car', 'documentable');

Кастомные полиморфные типы

Для примера выше можно указать свои имена моделей:

Relation::morphMap([
    'rider' => 'App\Driver',
    'auto' => 'App\Car',
]);