Какие типы связей между моделями поддерживает Eloquent ORM в Laravel?

Ответ

В Laravel Eloquent я активно использую все типы связей для построения сложных моделей данных. Основные из них:

  1. Один к одному (One-to-One) Связь, где одна запись модели A относится к одной записи модели B. Например, у User есть один Profile.

    // В модели User
    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
    // Использование: $user->profile->bio;
  2. Один ко многим (One-to-Many) Одна запись модели A имеет много записей модели B. Классический пример: у Post много Comment.

    // В модели Post
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
    // Использование: $post->comments->each(...);
  3. Многие ко многим (Many-to-Many) Связь через промежуточную таблицу. Например, User может иметь много Role, и роль может быть у многих пользователей.

    // В модели User
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
    // Eloquent автоматически использует таблицу `role_user`.
    // Получить всех пользователей роли: $role->users;
  4. Связь «Через» (Has Many Through) Позволяет получить доступ к удаленной связи через промежуточную модель. Например, в проекте у Country есть много User, а у каждого User много Post. Чтобы получить все посты страны:

    // В модели Country
    public function posts()
    {
        return $this->hasManyThrough(Post::class, User::class);
    }
    // Eloquent выполнит JOIN через таблицу users.
  5. Полиморфные связи Позволяют модели принадлежать более чем одному типу другой модели на одной ассоциации. Использовал для реализации комментариев к разным сущностям (Post, Video).

    // Модель Comment
    public function commentable()
    {
        return $this->morphTo();
    }
    // Модель Post
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
    // Теперь можно получить $post->comments или $video->comments.

Ключевое преимущество Eloquent — декларативный синтаксис и «ленивая»/«жадная» загрузка (with()), которая позволяет оптимизировать запросы и избегать проблемы N+1.

Ответ 18+ 🔞

Э, слушай, а Laravel Eloquent — это вообще пизда рулю, если честно. Я там все эти связи по полной использовал, чтобы модели не выглядели как мартышлюшка с одной палкой. Вот, смотри, как оно бывает.

Один к одному (One-to-One) Это когда у одной сущности есть ровно одна прицепленная хуйня. Ну, типа, у User может быть один Profile. Не два, не ноль, а один, блядь. Как нос на лице.

// В модели User пишешь
public function profile()
{
    return $this->hasOne(Profile::class);
}
// А потом просто $user->profile->bio; и всё, ты уже знаешь, какой он мудак.

Проще простого, ёпта.

Один ко многим (One-to-Many) А вот это уже веселее. Одна запись может иметь кучу других. Классика: у одного Post — дохуища Comment. Особенно если пост про политику, там комментов будет овердохуища.

// В модели Post
public function comments()
{
    return $this->hasMany(Comment::class);
}
// А потом $post->comments->each(...); и читаешь этот трёп до потери пульса.

Многие ко многим (Many-to-Many) Вот тут начинается магия, блядь. Связь через промежуточную таблицу. Например, User может быть в куче Role, и одна роль может быть у толпы пользователей. Как в армии: все солдаты — дебилы, и каждый дебил — солдат.

// В модели User
public function roles()
{
    return $this->belongsToMany(Role::class);
}
// Eloquent сам догадается, что нужна таблица `role_user`, хитрая жопа.
// Получить всех юзеров роли: $role->users; — и вот ты уже видишь всю свою паству.

Связь «Через» (Has Many Through) А это для тех, кто любит копать глубже, ебать копать. Позволяет дотянуться до чего-то через прослойку. Допустим, есть Country, в ней живут User, а эти юзеры пишут Post. Как получить все посты страны? Да не вопрос!

// В модели Country
public function posts()
{
    return $this->hasManyThrough(Post::class, User::class);
}
// Eloquent сам сделает JOIN через таблицу users, а ты сиди и пей кофе. Удобно, блядь.

Полиморфные связи А вот это, чувак, высший пилотаж, ёперный театр! Позволяет одной модели прилипать к разным другим на одной ассоциации. Я это использовал для комментариев, которые можно оставить и под постом, и под видео, и под фоткой кота.

// Модель Comment
public function commentable()
{
    return $this->morphTo();
}
// Модель Post
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}
// И теперь $post->comments или $video->comments работают как часы. Красота, ядрёна вошь!

Главный плюс Eloquent — это то, что он умный, блядь. Не нужно вручную городить эти JOIN'ы, как будто на дворе 2002-й год. Декларативный синтаксис, «ленивая» загрузка, а главное — метод with() для жадной загрузки. Без него начнётся проблема N+1, и твоё приложение будет грузиться как хуй с горы, пока ты будешь охуевать от количества запросов. А так — один запрос, и все связи подтянулись. Волшебство, да и только.