Laravel: Understanding Eloquent Relationships… with drawings!
Everything just becomes more easy when you put some pictures on it
Creating an application from scratch takes time. Creating the database schematic also takes time. And getting both right takes more time!
Eventually you will come to relationships, or how a record is related to another. The idea that Eloquent Relationships propose is simple: give the developer a way to retrieve a single or multiple related records for another record in an expressive way, with some prior and minor configuration. You set a value that relates them, and then you’re a method away to do anything you want.
The relationships are relatively easy to understand, but some people may get lost easily when you don’t have any drawing or schematic showing you what it can’t be said with words — one of the few difficulties of reading the Laravel documentation is that there is no pictures. Being said that, I decided to make my own and put them here for future reference.
Also, I made this by hand. I brought up the artist that lives in me. Sorry if you feel bad for not having the same m4d sk1llz like me. Let’s start.
One to One
The One to One is very simple: one record is connected to another record in another table. One of the records is the Parent, and the other is the Child. These are defined by hasOne()
and belongsTo()
respectively.
The Child model has the pointer to the Parent, which is usually mirrors the primary key of the Parent record, but with Eloquent ORM it can be anything else.
Deleting the Parent model will leave the Child model orphaned… The more you know 🌟.
One to Many
The One to Many it’s the same as a One to One relationship, but the Parent record can have many Childs, since multiple Childs can point to the same Parent. The method changes, which is now hasMany()
— this basically instructs Eloquent ORM to expect many records instead of one.
When you query the relationship, you won’t get one, but a Collection of related records, even if only one Child record exists.
Many to Many
The Many to Many relationship is more difficult to understand. Basically, a record can be linked to many others records, and the other way around.
A pivot table is what makes this possible. It connects one record from one table to the other, has many times needed. If the pivot table disappears, then both tables became unlinked, since the link information is only in this table.
For example, the pivot table may have three records pointing to the same foo.id = 2
record, but the each points to a bar.id = 1
, bar.id = 2
, and bar.id = 4
. The same thing can happen in reverse.
Has One Through
The Has One Through gets another record using an intermediate table, that in this case works pretty much like a pivot table — each record holds a reference to a bar
record and a quz
record, connecting them both.
To better imagine how this works, I’m gonna take the same example in the Laravel docs, and take a picture of the database, so you can get the idea of how it reaches the other table:
As you can see, the resulting SQL query will use the users
table to reach the history
table records.
Has Many Through
The Has Many Through works much like the Has One Through, but the difference is that one record can have many far relations.
Let’s take the same documentation example, where it offers a way to gather many Post from a single Country. As you can imagine, the users
table acts like a Pivot table.
As you can see, many users can have the same Country ID, and many post can have the same User ID. With some SQL magic, you can retrieve the posts from a given country in one statement.
One to One Polymorphic
The One to One Polymorphic is the same as the One to One, but the Child record can point to different tables, hence, different Parent Models. This needs two columns, one that holds which table and which ID of the record.
The morphTo()
method goes in the Child table, while the morphOne()
goes to the Parents models. In other words, this type of relations allows a Child to have many types of Parents — sounds weird but it has to be remarked.
One to Many Polymorphic
This one it’s the same as One to Many, but in this example the bar
and foo
models can take many records of the quz
model. As you can see, the models that use the morphMany()
method can be considered as the Parents, and can have many Childs, but the difference is that these Parents can be of any type.
This is because multiple records in the Child table can point to the same Parent.
Many to Many Polymorphic
Same as the Many to Many, where a Pivot table is in charge of unraveling the relation. To be clear, the Child Models are not limited by one Parent relation any more, but to any that can accept it.
In this graphic, the Bar and Foo models can have many Quz thanks to the Pivot table “Quzables” which is in charge of connecting the Parents with the Childs. Also, one single Quz can have many Foo or Bar. MADNESS!
And that’s pretty much it. Happy coding.