DEV Community

Jeroen van Rensen
Jeroen van Rensen

Posted on • Originally published at jeroenvanrensen.nl

Eloquent relationships explained (with examples)

In my opinion, Eloquent is one of the most powerful features of Laravel. It is an API for interacting with your database, and it has a very nice and easy-to-remember syntax. For example:

$post->author->name;
Enter fullscreen mode Exit fullscreen mode

Will give you the name of the post's author.

This is an example of an Eloquent relationship. Relationships define how your models (tables) are connected. Although most are easy to understand, there are a few more complicated ones.

In this post, I'm going to show how every relationship works.

One to one (has one)

For this example, we have two models: a User and an Address. The User model holds information such as name, email address, and password, and the Address model holds information like country, state, city, etc.

  • A User has one Address
  • An Address belongs to a User

We may have this table structure:

users
    id - integer
    name - string
    email - string
    password - string

address
    id - integer
    country - string
    city - string
    user_id - integer
Enter fullscreen mode Exit fullscreen mode

You can define these relationships like this:

// app/Models/User.php

public function address()
{
    return $this->hasOne(Address::class);
}
Enter fullscreen mode Exit fullscreen mode

Now you can access the user's address using $user->address->city.

Note: for this to work, the Address model should have a user_id column.

Inverse (belongs to)

If you have an Address and want to find the corresponding User, then define this relationship:

// app/Models/Address.php

public function user()
{
    return $this->belongsTo(User::class);
}
Enter fullscreen mode Exit fullscreen mode

One to many (has many)

In this example, we have two models: a Post and a Category.

  • A Post belongs to a Category
  • A Category has many Posts

And we have this table structure:

categories
    id - integer
    name - string

posts
    id - integer
    title - string
    category_id - integer
Enter fullscreen mode Exit fullscreen mode

We can define this relationship like this:

// app/Models/Category.php

public function posts()
{
    return $this->hasMany(Post::class);
}
Enter fullscreen mode Exit fullscreen mode

And you can access all the posts like this:

foreach($category->posts as $post) {
    //
}
Enter fullscreen mode Exit fullscreen mode

Note: for this to work, the Post model should have a category_id column.

Many to one (belongs to)

In this example, we have two models: a Post and a Category.

  • A Post belongs to a Category
  • A Category has many Posts

And we have this table structure:

categories
    id - integer
    name - string

posts
    id - integer
    title - string
    category_id - integer
Enter fullscreen mode Exit fullscreen mode

We can define this relationship like this:

// app/Models/Post.php

public function category()
{
    return $this->belongsTo(Category::class);
}
Enter fullscreen mode Exit fullscreen mode

And you can access the Post's category like this:

$post->category->name;
Enter fullscreen mode Exit fullscreen mode

Has many through

This relationship is a bit more difficult. In this example, we have three models: an Author, a Post, and a Language.

  • A Post belongs to an Author
  • An Author has many Posts
  • An Author "belongs" to a Language (speaks a language)
  • A Language has many Authors

For example, this is our table structure:

languages
    id - integer
    name - string

authors
    id - integer
    name - string
    language_id - integer

posts
    id - integer
    title - string
    author_id - integer
Enter fullscreen mode Exit fullscreen mode

If we want to get all posts in a specific language, we can define this relationship:

// app/Models/Language.php

public function posts()
{
    return $this->hasManyThrough(Post::class, User::class);
}
Enter fullscreen mode Exit fullscreen mode

Now, we can get all posts using:

foreach($language->posts as $post) {
    //
}
Enter fullscreen mode Exit fullscreen mode

Inverse

If you now want to get the Language of a Post, you can just simply do this:

$post->user->language->name;
Enter fullscreen mode Exit fullscreen mode

Many to many (belongs to many)

In this example, we have two models: a Product and a Tag.

  • A Product has many Tags
  • A Tag has many Products

And we may have this table structure:

products
    id - integer
    name - string
    price - integer

tags
    id - integer
    name - string

product_tag
    product_id - integer
    tag_id - integer
Enter fullscreen mode Exit fullscreen mode

Note: in the table structure, we have a third table, product_tag. This table connects products to tags.

Now we can define the relationships like this:

// app/Models/Product.php

public function tags()
{
    return $this->belongsToMany(Tag::class);
}
Enter fullscreen mode Exit fullscreen mode
// app/Models/Tag.php

public function products()
{
    return $this->belongsToMany(Product::class);
}
Enter fullscreen mode Exit fullscreen mode

Now we can get all tags/products using:

foreach($product->tags as $tag) {
    //
}
Enter fullscreen mode Exit fullscreen mode
foreach($tag->products as $product) {
    //
}
Enter fullscreen mode Exit fullscreen mode

In the next post, I'm going to show what polymorphic relationships are and how to use them. Thanks for reading!

Top comments (0)