The Beginner Guide To Laravel ORM:Legacy Perspective (Part 3)
In the previous article I already explain on how do we do One-To-Many relationship using Laravel ORM in the context of legacy database.
In this article I will explain how we can implement Many-to-Many relationship using Laravel ORM. If you look into laravel documentation, this relationship is said to be a bit complicated than the One-to-One and One-to-Many relationship, and it is. But don’t worry, I will try my best to explain this relationship in plain language.
As usual, Let’s take a look at the picture below.
As you can see, the picture above can be translated as many-to-many
relationship when we say, a user has many books and the a book has many authors(User)
.
We can achieve this relationship through the intermediate table (BookAuthor). This is how we implement many-to-many relationship in a database level.
For laravel implementation, we need to create BookAuthor
model.
The BookAuthor model is a regular model, nothing special, except that this model has no primary key. The reason why is that, this model used to make relationship between User and Book model.
In the User model, we add a relationship belongsToMany
to represent Many-to-Many relationship. But just as in laraval documentation, this is a bit complicated than the previous relationship explained in the articles. Take a look at thebooks()
method.
public function books(){
return $this->belongsToMany('App\Book','real_intermediate_table_name','foreignkey','otherkey');
}
From the User
model, we define books()
methods, where it returns belongsToMany
and we mention, both Book
and BookAuthor
and provide its key that make relationship for them.
The tricky part is that,if you look carefully, we don’t write App\BookAuthor
after the App\Book
model. Why is that? beacuse, in laravel documentation, we have to specify the table name
and not themodel name
. Follows are the definition for the terms I put on the belongsToMany()
method
- real_intermediate_table_name: table name in database, in this context (book_authors)
- foreignkey: (User) key that match with the intermediate model (BookAuthor). in this context , passport_number
- otherkey: (Book) key that match with the intermediate model (BookAuthor)
Before we run any command, you have to create the Book
model as shown below.
In the Book model, you have to pay attention to the $incrementing
property in the model, this is because the reverse relation will not work due to the convention that laravel employed in its framework. You can experiment it by disabling the property defined in this class.
Lets take a look at the authors()
method. If we compare the code with the books()
method, theres no different in term of convention and formatting. It is written in the same formula. But off course it will return different result unless we define the $incrementing
property.
By now, if you go to php artisan tinker
, and run the command App\User::first()->books
, viola.. it worked.
After that, try App\Book::first()->authors
, yeah.. it worked too.
Expected output:
Important points to note:
1. User Key :passport_number (string)
2. Book Key :isbm (string)data retrieval from User -> Book, Okdata retrieval from Book -> User, Not OkWhy????... the reason why is that, on the reverse relation, Book model recognise isbn as an integer,even if we try to get App\Book::first()->authors, this will return empty. when we look into details, in its query, it tries to match isbn=0
As a conclusion, we see that laravel ORM can still be implemented for legacy database with a few tweaks. Nice. So in the next article, i will show you how to deal with Has Many Through relationship.
I hope this article can help you in your context of your own.
Thanks for reading..