Skip to main content

Basic Eloquent Relationships

· 5 min read
Alexis Fraudita

One of the most challenging parts of web development I've experienced is the relationship between tables in relational databases; it always leaves me perplexed. Fortunately, in Laravel, there is a fantastic resource called Eloquent which has been a lifesaver for me.

Laravel Eloquent Relationships make it easy to define connections between database tables and Eloquent models in PHP. These relationships make it simple to link data between tables, such as a comment associated with a particular blog post or an order linked to a particular user.

In this post, I will show you an introduction of how to use the basic relationships available in Laravel Eloquent.

One to one

The first relationship you can create is a “one-to-one” relationship. This relationship is pretty straightfoward, let's think on a parking monitor system where a User model is associated with a Car model. To set this up, we use the hasOne() and belongsTo() methods. You would define the table structure and the relationship like this:

User
id - integer
name - string

Car
id - integer
name - string
<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
public function car(): HasOne
{
return $this->hasOne(Car::class);
}
}

Then, on the Car model, you can define the inverse relationship like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Car extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

Once you have established the relationship between two models, you can use Eloquent's query builder to retrieve the associated models. For example, if you want to get a user's car, you can do the following:

$user = User:find(1);
$car = $user->car;

You can also use the inverse relationship to get the related user from a car:

$car = Car::find(1);
$user = $car->user;

One to many

Another relationship is ”one to many” , in this case the relationship is defined between a single model being the parent of one or more child models. For example if you have a Library model that “has” many Book models, you would define the table structure and relationship as follows:

Library
id - integer
name -string

Book
id - integer
name - string
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Library extends Model
{
public function books(): HasMany
{
return $this->hasMany(Book::class);
}
}

Then you can define the inverse relationship on the Book model like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Book extends Model
{
public function library(): BelongsTo
{
return $this->belongsTo(Library::class);
}
}

You can use the relationship to access the related models. For instance, to get all the books belonging to a specific library, you can do the following:

$library = Library::find(1);
$books = $library->books;

or

$book = Library::find(1)->books()->where('title', 'Moonguard')->first();

Or the inverse relationship to get the library associated with a particular book:

$book = Book::find(1);
$library = $book->library;

Many to many

A more complex relationship is the “many-to-many” relationship, where two models can have multiple instances of each other. For instance, we can create a blog where each post may have multiple authors, and each author may have multiple posts. To set up this relationship, you need to create three database tables: authors, posts, and authors_posts. The authors_posts table is a "pivot" table that stores the relationship between an author and a post. This way, you can have multiple authors associated with a post and multiple posts associated with an author. The table structure look like this:

authors
id - integer
name - string

posts
id - integer
name - string

authors_posts
authors_id - integer
posts_id - integer

Once we define the relationship table structure, we will define the eloquent relationship using the belongsToMany() method in the Author model like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Author extends Model
{
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class);
}
}

Then we define the inverse relationship:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Post extends Model
{
public function authors(): BelongsToMany
{
return $this->belongsToMany(Author::class);
}
}

Once it is define, you may access to the authors’posts.

use App\Models\Author;

$author = Author::find(1);

foreach ($author->posts as $post) {
// ...
}

Or you can get the Posts like this:

$posts = Author::find(1)->posts()->orderBy('name')->get();

That's enough for now - we can explore more complex relationships like polymorphic relationships in a future post.

Discover the secrets behind our successful software with our book "MoonGuard: The Software Creator’s Journey" to learn how to create successful Laravel package from scratch! In addition to our website, we also maintain an active presence on Twitter (@moonguard_dev). By following us on Twitter, you'll be the first to know about any breaking news or important announcements regarding MoonGuard. So be sure to check us out and stay connected!