Defining many-to-many0:00
Next up, we have the slightly more confusing mini-to-mini relationship. So take a look here. I have a list of films. But what if I wanted to know which actors starred in each film? Well, we do have an actors table here. So think about it. Ask yourself this. I don't see a relationship between this actor and the film. So would it be okay to add a film_id column? And that way, for example, NickWahlberg could have a film_id of 1.
So we're starting to see we have a slightly different relationship in place. No single Actor belongs to a Film. They can belong or star in many Films. So this right here is the formula or the equation for a mini-to-mini relationship. Any Film can have many Actors. And any Actor can star in many Films. So notice on both sides of the equation, we have a single record that can be associated with multiple records from the other table. This Film has many Actors. But this Actor stars in many Films or can star in many Films.
Using a linking table1:36
We do that through what's known as a linking table. We're literally linking one table to another. So think of it sort of like a chain. So notice here we have as many columns as we need to. But most importantly, we have the primary keys from the two tables that form the relationship. So if I have a relationship between a Film and an Actor, the table name, by common convention, it doesn't have to be this way, but a common convention is it consists of the names of the two tables together. That way I can see the Actor with an ID of 1 starred in the Film with an ID of 1. So let's see.
That way I can see the actor with an ID of 1 starred in the film with an ID of 1. So let's see. Who's the actor? Penelope Guinness. So Penelope Guinness starred in Academy Dinosaur. But also Penelope Guinness starred in, right here, Anaconda Confessions. So again, we have that many-to-many relationship in place. Now if we take a look at the makeup, again, we have the two primary keys as well as anything else that might be appropriate. And sometimes it will be things like timestamps, extra timestamps that you might want to add.
Tags as example2:34
else that might be appropriate. And sometimes it will be things like timestamps, extra timestamps that you might want to add. But you're not limited there. And then we do have some relationship constraints in place. Okay, so now that you understand it, let's switch back to our tutorial database. So I have users, profiles, posts. Let's do the common example of tags. So any one blog post can have many tags. So if I have a tutorial about Laravel, I might tag it Laravel. I might tag it programming.
So if I have a tutorial about Laravel, I might tag it Laravel. I might tag it programming. I might tag it work. So any one blog post can have multiple tags. However, on the flip side, the Laravel tag doesn't belong to that post. That Laravel tag can be applied to any number of posts. So once again, on both sides of the equation, a single post or a single tag can be associated with multiple records from the opposing table. So let's switch to Laravel and represent this. The first step is I need a table for my tags.
Creating tags table3:30
So let's switch to Laravel and represent this. The first step is I need a table for my tags. So I will generate a migration called createTagsTable. And now to keep it very, very simple, a tag consists of just the name. And we might even want to shorten that by a good bit. All right, so I will migrate my database. And if I now switch back to SQL Pro, and we give it a refresh, now we have a list of tags. And I will add just a handful real quick, Laravel. How about programming? And then finally, how about personal?
Building pivot table4:04
How about programming? And then finally, how about personal? Okay, great. So now I want to say this blog post, and we'll call it LaravelPost, should be associated with two of those tags, Laravel and programming. All right, we need to set up a linking table. So we'll do that now. Now I could create a second migration, but just to keep it very quick, I'm going to do it here, and then we'll refresh our migrations. So we'll say Schema::create, and what are the two tables here?
it here, and then we'll refresh our migrations. So we'll say Schema::create, and what are the two tables here? We have posts and tags. So we'll call it post_tag by convention. Now I'm going to leave the primary key here, but you can actually remove it if you want or keep it. It sort of depends, but we'll keep it for now. post_tag needs to have the primary key of the related post, and it also needs the primary key of the related tag. And then we'll set up our foreign key here.
key of the related tag. And then we'll set up our foreign key here. So we'll say, or our foreign constraint, the post_id references the id column on the posts table. And if you were to delete the post, cascade and delete this record as well. And we'll do the same thing for the tag_id. All right, now there is one other thing related to uniqueness that we'll talk about in a minute, but let's leave it like that. All right, so I'm going to roll back my migration and then rerun it. Okay, so now if I switch back and give this a refresh, we have our tags table, and we
All right, so I'm going to roll back my migration and then rerun it. Okay, so now if I switch back and give this a refresh, we have our tags table, and we also have our new linking table. So very quickly, I've lost my tags, so I will run a command to bring them back. There we go. Okay, so now think about it. If I want to say this Laravel Post has a tag of Laravel in programming, we can set that up. So the post with an ID of one has a tag of one, which is Laravel. And then we'll do another one.
So the Post with an ID of one has a tag of one, which is Laravel. And then we'll do another one. The Post with an ID of one also has a tag of programming. Finally, let's do one other one real quick, just to show you. Another Laravel Post. And then there, that has an ID of three, we will also give that a tag of Laravel. So now let's say we want to fetch all Posts that have been assigned to that tag. Well, as an SQL query, I could say SELECT * FROM posts, but let's left join the linking table on the condition that the linking table's post_id matches up with the ID of the Post. Finally, I want to limit it to only the Posts that have a tag of Laravel, which is one.
table on the condition that the linking table's post_id matches up with the id of the post. Finally, I want to limit it to only the posts that have a tag of Laravel, which is one. So where post_tag.tag_id equals one. And there we go. Now we have two posts along with their tags. So if we create another record here, we'll say something personal. And we give that a tag. So this has an id of five. We'll do another one here. The post with an id of five has a tag of three, which is personal.
Eloquent many-to-many usage7:09
We'll do another one here. The Post with an ID of five has a tag of three, which is personal. If I run that query again, I'm still only going to get the posts that have a tag. If I wanted the other ones, I would do that. So pretty easily, we use this linking table to fetch only the posts we care about. And in this case, it's posts that are associated with a given tag. All right. So final step, let's programmatically represent this. So we have a Post. The relationship between a Post and tags is a manyToMany.
So we have a Post. The relationship between a Post and Tag is a many to many. So I can say return this belongsToMany. Now, I don't think I have a Tag model yet. No, we forgot to do it. There we go. So now I have this direction. Let's do it in the other direction. And if it's a many to many on both ends, then it's basically the same thing. If I have a given Tag and I want to fetch the Posts associated with it,
And if it's a many-to-many on both ends, then it's basically the same thing. If I have a given tag and I want to fetch the posts associated with it, it's a many-to-many relationship. All right. Let's try it out. So we know that a Laravel Post has two tags, this one and this one. Let's try to find it with Eloquent. I'm going to find my post. And then I'll say, give me the tags for that post. And we get two, Laravel and programming.
And then I'll say, give me the tags for that Post. And we get two, Laravel and programming. Let's do one other one. The Post with an ID of 5 should have a personal tag. Post tags. And there we go. And we can also do it the other way around. So if I have a tag with an ID of 1, let's find that. And I want to fetch the Posts associated with it. I can see for that given tag.
And I want to fetch the Post associated with it. I can see for that given tag. You know, maybe on your website, you visit example.com/tags/Laravel. All right. Well, in your controller, you will find that tag and then fetch the posts associated with it. Now, finally, a little tip here. If you're ever playing around with this and you're curious what Laravel is doing, you can either install Laravel Telescope or you can do a simple DB::listen. If you're playing around in tinker. So, for example, you could var_dump the SQL and the bindings.
If you're playing around in tinker. So, for example, you could var_dump the SQL and the bindings. All right. Let's give it a shot. So if I were to say, give me the first Post. Yes, I get the Post. But you can also see the query that was executed. So you can use this to toy around. Like if you want to find the Post with an ID of one, but also get the tags associated with it. Here is what Laravel is actually doing.
Like if you want to find the Post with an ID of one, but also get the tags associated with it. Here is what Laravel is actually doing. And there you have it. Many to many relationships.
