Laravel Eloquent relations — The basics

Jonathan van Rij
4 min readOct 20, 2022

--

Eloquent is the database abstraction layer Laravel uses. Are you new to Laravel? Then I hope this article helps you out with the first steps you’re taking with Eloquent.

Laravel Eloquent supports different types of relations. These are the most crucial basics to get you going when you’re new to Eloquent.

Before you read on, it is good to know that all these examples comply to the Laravel naming convention.

Here are some important notes you should know for a better understanding of it all:

A model is an object representation of a row from the database.

A table is written in snake_case plural: article_comments

A foreign key is always a snake_case of the table name with id: table_name_id.

A model is always singular PascalCase: ArticleComment

Relation methods are written in camelCase singular or plural depending if the relation can return multiple models: $model->articleComments() or $model->articleComment()

When you comply to this convention you can leave out a lot of code because Laravel will assume the correct field and table names. This will save you a lot of time!

When you call a relation like an attribute, depending on it being singular or plural, Laravel will return the single model or a collection of models.

Let’s start with the BelongsTo relation…

Belongs to

A Post is written by an Author, so the Post BelongsTo the Author. In this relation the posts table has an author_id field containing the foreign key to the authors table.

On the Post model the relation is defined like this:

public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}

Connecting a Post with an Author can be done like this:

$post->author()->associate($author);
$post->author()->dissociate($author);

When the relation is set up properly you can retrieve the Author model like this:

$post->author

The inverse relation of BelongsTo is both HasMany and HasOne. You can use HasMany in cases like posts and authors because authors can have multiple posts. You can use HasOne in a situation where the Author (in this case) needs to relate to only one. Think of a primary Phone.

HasMany

Multiple posts are written by one Author, so the Author HasMany posts. In this relation the posts table has an author_id field containing the foreign key to the authors table.

On the Author model the relation is defined like this:

public function posts(): HasMany
{
return $this->hasMany(Post::class);
}

Connecting a Post with an Author can then be done like this:

$author->posts()->save($post);

Laravel will update the posts.author_id field with the author’s id.

When the relation is set up properly you can retrieve a collection of the posts like this:

$author->posts

When you call the relation method you will get a HasMany object which is also a (query) Builder.

// Collection of published Post models related to $author.
$author->posts()->where('published', true)->get();

HasOne

HasOne works exactly the same as HasMany only with one deviation. That is that Laravel always assumes there is only one related model.

One Post is written by one Author, so the Author HasOne Post. In this relation the posts table has an author_id field containing the foreign key to the authors table just like the HasMany.

On the Author model the relation is defined like this:

public function post(): HasOne
{
return $this->hasOne(Post::class);
}

And just like the HasMany, Connecting the Post with the Author can then be done like this:

$author->post()->save($post);

When the relation is set up properly you can retrieve the Post model like this:

$author->post

ManyToMany

A ManyToMany relation is used when both models can relate to multiple models on the other side of the relation. Think of multiple Tags that can relate to multiple Posts, but also the other way around.

For this relation to work there needs to be an extra pivot table containing foreign keys to both the models tables. The name of this table must be an alphabetical combination of the two related tabels in plural. In this example, the table name would be post_tag, and the foreign key fields post_id and tag_id.

On the Tag model the relation is defined like this:

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

On the Post model the relation is defined like this:

public function tags()
{
return $this->belongsToMany(Tag::class);
}

You can associate and disassociate the models from each other like this:

// On the post model
$post->tags()->attach($post);
$post->tags()->detach($post);
$post->tags()->sync([1,2,3]);
// On the tag model
$tag->posts()->attach($tag);
$tag->posts()->detach($tag);
$tag->posts()->sync([1,2,3]);

Or you can sync all the related models, this will overwrite all related models on the specific model.

// On the post model
$post->tags()->sync([1,2,3]);
// On the tag model
$tag->posts()->sync([1,2,3]);

The related models can be retrieved like this:

$post->tags

When you call the relation method you will get a HasMany object which is also a (query) Builder.

// Collection of published Post models related to $tag.
$tag->posts()->where('published', true)->get();

I hope this gets you going!

Are you up for the next step, or you’re just in need of a relation from one Model to multiple other Models? Then check out my next article about Laravel Eloquent. Laravel Eloquent relations — MorphTo.

--

--

Jonathan van Rij
Jonathan van Rij

Written by Jonathan van Rij

Freelance web developer @ Blijnder. Passionate developing applications in Laravel and Statamic CMS.

No responses yet