Many-to-Many Overview0:03
The many to many relationship is much more complex than one-to-one or one to many. You'll see why here in a moment. But you know, as far as an example is concerned, think of users and teams. I'm not talking about sports teams, but you know if, if you've used Slack or Teams or any one of those kinds of applications, you can be assigned to multiple teams. So a user can have multiple teams
Creating Team Model0:25
you can be assigned to multiple teams. So a user can have multiple teams and a team can have multiple users. That's what we call a many to many relationship and that's the example that we are going to follow. So let's start by creating a new model called team. We of course win our migration in our factory. And let's go ahead and define the schema for the team table
And let's go ahead and define the schema for the team table or the team table I should say. And this is going to be very simple. All we need is a column for the name. There's no relationship information here because we can't really put any information for a relationship because if we do add a foreign key, what are we doing? We are setting up a one-to-one or one-to-many relationship.
because if we do add a foreign key, what are we doing? We are setting up a one-to-one or one-to-many relationship. And you know, you could think, okay, we could have multiple foreign keys for the user table, it won't work. And even if it did this, this isn't a feasible approach because we are essentially giving ourselves a hard limit on how many users can be assigned to a given team. So no, there's no relationship information in our team whatsoever.
Building Pivot Table1:40
So no, there's no relationship information in our team whatsoever. Instead what we have to do is create another table. We call it a pivot table. You might also hear it called a linking table, but that's exactly what this pivot table does. It links a record from the user table to a record in the team table, thus creating the connection or the relationships so that we can have many users with many teams and many teams with many users.
or the relationships so that we can have many users with many teams and many teams with many users. So we want to create another table. So let's use Artisan to make a migration. We'll call it create team user table. Now the name of this table is important because there is a convention when it comes to creating pivot tables. We need to list the names of the tables in alphabetical order
We need to list the names of the tables in alphabetical order and also we want to use the singular form of those tables. So we are working with users and teams, but alphabetically teams comes before user. So we call it team underscore user. Now we can actually call this whatever we want, but in doing so, whenever we set up the relationship in our our eloquent models, we have to tell it what table that we use.
whenever we set up the relationship in our our eloquent models, we have to tell it what table that we use. If we just use the convention, then eloquent is going to make everything work behind the scenes. So let's just follow the convention because makes our lives easier. Now we don't want an id. Now, yes, we want a primary key. I'm a firm believer in that every table needs a primary key, but an ID isn't going to be good enough for a pivot table. And I'll tell you why here in a moment.
but an ID isn't going to be good enough for a pivot table. And I'll tell you why here in a moment. Let's first of all create a foreign key for the user table, but it's not good enough just to set up a foreign key. We want to call constrained because we want to set up that referential integrity because once again this is going to create a relationship between a given user and a given team. We want the user to exist before we try to create this relationship,
We want the user to exist before we try to create this relationship, but we also want to call cascade on delete because if we delete a user, there's no sense to keep that relationship in place. So we will delete this record in this pivot table, thus getting rid of that relationship. But we also want to do the exact same thing for the team. So we have a foreign ID for the user id, we have a foreign ID for the team id.
So we have a foreign ID for the user id, we have a foreign ID for the team id. Both of those are constrained. Both of those are cascade on delete. So we have our foreign keys set up, but we can also do this, we can create what we call pivot data. So I want to give a user a role for whatever team that they are assigned to. And this pivot data isn't user specific,
for whatever team that they are assigned to. And this pivot data isn't user specific, it's not team specific, it is specific to this particular relationship. So if we have user A assigned to team A, the pivot data is going to be for that particular connection and nothing else. So we can say that the role will be something like an owner, uh, kind of making that person an admin of that team or a member or a guest.
uh, kind of making that person an admin of that team or a member or a guest. But we'll set the default to member and we can have other pivot data if we want to. In this particular case role is gonna be fine. So that's gonna be enough for us. But then we do want our primary key and in this particular case we want a composite primary key because we are working with essentially two. Well they are two unique pieces of information.
because we are working with essentially two. Well they are two unique pieces of information. You know, the user ID is unique in the user's table. The team's ID is unique and the team's table. But when it comes to the relationship, the combination between the user ID and the team ID needs to be the primary key because we want uniqueness in this pivot table. We don't want to assign user A to team a multiple times, we just want to do it once.
Defining Eloquent Relationships5:52
We don't want to assign user A to team a multiple times, we just want to do it once. And with that we're done with our pivot table. But of course that's just the database level. We also need to set up the relationship at the eloquent level. So let's open up our user model as well as our team model. We'll start with the user because this is where we have, you know, the has one relationship to the profile
because this is where we have, you know, the has one relationship to the profile that has many relationship to the tasks. Now we want a relationship for our teams and this is a belongs to many relationship. And just like the other relationships we return belongs to many, we specify the name of the model that this relationship is with, which is the team. And you know, that could be it. But we also want to take this a step further
And you know, that could be it. But we also want to take this a step further because we have that pivot data and anytime that we are going to work with this relationship, we could also assume that we would want easy access to that pivot data. So we're gonna call the with pivot method so that we will include whatever pivot information that we want. In this case we just have the role, so that's
information that we want. In this case we just have the role, so that's what we are going to include, but we can also include the timestamps. So let's do that as well. And what we do inside of the user model, we also have to do inside of the team model. Except that here, let's first of all add the fillable and what was that? It was just the name column, wasn't it?
fillable and what was that? It was just the name column, wasn't it? Then we have our relationship, but you know, we just need to make a few changes. The relationship is to our users, it is still a belongs to many, but now that relationship is with the user model and everything else is going to be left the same. So now that we have our eloquent relationship all set up and ready to go, now we just need to write our team factory so
Seeding Relationship Data7:54
and ready to go, now we just need to write our team factory so that we can easily create some teams and let's use Faker and we'll call the company method because a company name is gonna be good enough for a team name. And then we just need to open up the database Cedar because we need some test data. Now we already have this code to create our users
because we need some test data. Now we already have this code to create our users and their profiles and their tasks teams are gonna be a little bit different. So let's do this. We will create our teams by using the factory. We'll create five teams and then inside of this closure here, we will get a random set of teams that we will then attach to a particular user.
a random set of teams that we will then attach to a particular user. So we have our teams, let's have random teams so that we'll call teams random. And let's say that we went random from one to four, so that then we can iterate over the random teams as team. And then for our user, we'll use the team's relationship object to attach the given team by its id.
we'll use the team's relationship object to attach the given team by its id. So whenever we want to attach a team to a user or if we want to attach a user to a team, we have to do so by the id. So in this case, we are attaching a team to a user. So we use the team's id, but then we also have that pivot information. So we want to include that here. And we have the three values, uh, owner, member, guest.
So we want to include that here. And we have the three values, uh, owner, member, guest. Let's create a collection of those values and then we will just pick one at random. So we have owner, member guest and then random. So that should work. We create our teams, we create a random number of teams, we iterate over those random teams, we attach each team by the team ID to the user, and then we set the pivot data there.
by the team ID to the user, and then we set the pivot data there. So we should be ready to go. All we have to do is run our migrations with PHP Artisan migrate fresh seed. Hopefully everything's gonna work. And sure enough it does. But let's take a look at the database because I think this will help us understand how all of this works. So we of course have our users, we have our teams
understand how all of this works. So we of course have our users, we have our teams and by themselves they're just individual teams and individual users. But if we look at the team user table, we have a different picture. Each record defines a relationship between a given user and a given team. And then we have the pivot information for that relationship.
And then we have the pivot information for that relationship. So user with an idea of one is a member of team with an idea of two and they are an owner of that team. User with an idea of two is a member of team with an idea of three and they are a guest, but they are a member inside of the team with an idea of four and they are the owner of a team with an idea five. So I'm not gonna go through this whole thing, but you can see how this works.
Working With Pivot Data11:05
So I'm not gonna go through this whole thing, but you can see how this works. Every record defines a relationship between a single user and a single team. Then we have that pivot information to provide extra information about that relationship. So let's start by going to our routes and to prepare for this episode, I have created a UI that we can use that will allow us to manage our teams and our users so that we can assign users to teams
that we can use that will allow us to manage our teams and our users so that we can assign users to teams and teams to users. And all of this is ready to go and it's in the GitHub repository. So if you want to follow along, look for the episode three prep branch. However, before we get into that, there are some things that I want to point out. So we're gonna create a route.
that I want to point out. So we're gonna create a route. So that's what we are going to do is just output some json and we're gonna start by just fetching a particular user and it doesn't matter. So we will find the user with an ID of two and for right now, let's just return that user so that inside of the browser we of course see the type of information that we would expect. We have the user information
of information that we would expect. We have the user information and there's no other relationship information, which of course we didn't include. So we could say with teams and then we would want to find the user with an idea of two. And if we take a look at the browser, we will see not just the user information but of course all of the team information as well. And it's not just the team information,
but of course all of the team information as well. And it's not just the team information, but we are also including the pivot information. Now there are gonna be times when you want to hide that pivot information. Most of the time it's gonna be when you want to output Jason, which is why I picked this particular scenario. But you can easily hide that pivot information by accessing our relationship, not calling the method mind,
But you can easily hide that pivot information by accessing our relationship, not calling the method mind, but just accessing the teams. And we can call the make hidden method. Then we just need to say that we want to hide the pivot information so that now we output the user information and the team information, but that pivot information isn't included. But what if you need to work with some of the pivot information?
But what if you need to work with some of the pivot information? Like for example, maybe we don't want to output the entire user information, maybe we just want the username, the first team, and then the role that the user is assigned for that team. So if we could do something like this, we could have teams, but then we want to get the first team, in which case that's going to give us all of the information that we need. We just need to output the appropriate information so
that's going to give us all of the information that we need. We just need to output the appropriate information so that we would have the user, as user, we'll just return all of the user stuff, then we'll have the first team as our team. But in this case, let's just, I'll put the name, but then we want to know the role of the user with this given team, in which case we will use our team and we want to access our pivot information. And we do that with this pivot object.
and we want to access our pivot information. And we do that with this pivot object. This gives us access to all of the pivot information that we have included with this relationship, which in our case is the role. So this is going to output the user, the first team name and the role of that user. So if we go back and refresh, we are seeing all of these teams, I guess we shouldn't do the user. So let's do the user name
of these teams, I guess we shouldn't do the user. So let's do the user name that way we just see the username, the first team name, and then the user's role in that team. So anytime that you want to access the pivot information for a relationship, you do that through the relationship. In this case, we are approaching it from the user, so it's user and then the team. And then we get the pivot information. Now this pivot information is just uh,
And then we get the pivot information. Now this pivot information is just uh, it's a a basic object and by itself it's rather limited. You know, with our models we can create, you know, accesses. Let's open up uh, let's say our user model. And let's say that we wanted to get to the count of our teams so we could create an accessor, we'll call it teams count attribute. If you're not familiar with an accessor, it begins with get or set.
If you're not familiar with an accessor, it begins with get or set. The idea being that we are creating an attribute to either get information or set information. So we are getting information, we're gonna call our attribute teams count, and then we end that with attribute because that is the convention and this is going to return an integer value so that we can return the teams
and this is going to return an integer value so that we can return the teams count in order to get the count. So this means we can go back to our routes here and we can say that we have this teams count, which will be the user teams count attribute. And if we view that we will now have this teams count property and we see that it is set to three. So this accessor is a very powerful thing and by default we can't do that
So this accessor is a very powerful thing and by default we can't do that with this pivot object, but we can actually create a pivot model. Let's do that right fast. Now there's no easy way to do this. So what we're gonna do is make a model and we can call it whatever we want. I'm gonna call it membership. The idea being that uh, this whole relationship
I'm gonna call it membership. The idea being that uh, this whole relationship between a user and a team is a membership relationship and that created our membership model. But we don't actually want a model here. What we want is a pivot model. So this membership is going to extend this pivot class and this works a lot like a model in that we can define our casts if we want to do that.
and this works a lot like a model in that we can define our casts if we want to do that. So let's do that. Our casts, which in this case we just have our role, which is a string, which is kind of redundant, but you know that ability is there. But we can also create accessories here. So we can create one called is owner, in which case this would return a boole in value. And all we have to do here is say this role equals
in which case this would return a boole in value. And all we have to do here is say this role equals owner, owner. So this membership model, if you will, essentially is that pivot object, but by itself eloquent doesn't know to use that. So we need to go back to our user model and our team model and we need to say using membership class. And this is going to tell eloquent to use this membership
membership class. And this is going to tell eloquent to use this membership as our pivot object basically. So inside of the user model we need that using membership, which means that we can go back here and we can include that is owner and we access that just like we did with our pivot. But it's not this, it's user pivot and then is owner. And in this case it's gonna be false because the user is not an owner but is owner is null
And in this case it's gonna be false because the user is not an owner but is owner is null and it's probably because I did it wrong. Uh, we don't need the user, we need the team there. So there we go. We can see that this user is not an owner because they are a guest. So this pivot object gives us the access that we need to work with that pivot information and we can create a pivot model to you know,
Listing Teams and Users18:58
to work with that pivot information and we can create a pivot model to you know, add any extra functionality that we would need to work with that pivot data. But now let's turn to our actual ui. So I have these routes all set up and ready to go. Right now they don't do anything. So if we look at the teams routes, it's just a blank page because all we are doing is returning nothing. What we want to do here is return the list of teams so
because all we are doing is returning nothing. What we want to do here is return the list of teams so that we can display the list of teams. And this view teams index is, well all it's doing is iterating over the teams so that we can see what those teams are. So let's go ahead and do that. We're going to return our view of teams index and we want to supply the teams by using our team model and we can call all and that is going to make this work.
and we want to supply the teams by using our team model and we can call all and that is going to make this work. We will see an error unexpected token because I didn't add a semi. So if we go back, now we have our list of teams, but notice that there is this user's column and it's blank. I don't want to list all of the users, I just want to list the count. Now you know, we had implemented this teams count for the user model.
Now you know, we had implemented this teams count for the user model. We could essentially do the same thing for the team. So let's do that, we'll call it users count and then we will simply return the count of the users and inside of that index view, let's find it for the teams. There it is. We just need to output that value, which is, let's see, see it's right here, this column here. So if we say team users count, then we will see the number of users
So if we say team users count, then we will see the number of users that are assigned to those teams. And that's all well and good. We know that that works. But there's actually a better way, instead of creating this custom accessor, what we can do is whenever we fetch our information from the database, instead of calling all, we can call this with count method and then we could specify the relationship that we need, which in this case would be users.
and then we could specify the relationship that we need, which in this case would be users. And then we would want to get those. And you know, this isn't specific to many to many relationships. We can use this with count method for one-to-one, which is kind of pointless. But we can also use it with the one to many. Anytime that we want to get the count of a relationship, we can do that.
Anytime that we want to get the count of a relationship, we can do that. And this is going to automatically create an attribute that we can use in, in this case called users underscore count because the name of the relationship is users and it's just gonna add an underscore count to that and create us an attribute that we can use. So if we go back to the browser, we're still gonna get the same information,
So if we go back to the browser, we're still gonna get the same information, but it's a little more efficient by taking that approach. So that means whenever we display the users, we can essentially do the same thing. In fact, let's just copy that code and we'll paste it in. We of course need to make a few modifications such as the view is user index. The data that we're gonna pass to the view is called users.
as the view is user index. The data that we're gonna pass to the view is called users. We want to fetch the user data with the count of the teams. But other than that, everything is going to work so that if we open up the index view for our users, we need to find that column to where we want to display the count, which is right there. And in this case we will say user teams count and if we go to the user list, we see our list of users, we see the number of teams
count and if we go to the user list, we see our list of users, we see the number of teams that they are members of. So that means if we go back to this Jason endpoint, you know where we had this teams count, well let's go ahead and let's get rid of that. We will comment out that accessor so that whenever we display this information we will fetch the with count method, we'll get that count, we'll still get the first team
with count method, we'll get that count, we'll still get the first team and everything else should work as it did before. So that's great. But let's go back to more exciting things like the teams list or the users list. Okay, so we are now working with those and we want to be able to assign users to teams and assign teams to users. So here we are at the teams.
Assigning Users to Teams23:44
and assign teams to users. So here we are at the teams. If I click on assign users, nothing is gonna happen because, well we haven't really implemented anything there. So I think we're done with our routes. So let's close a lot of things, most things now and let's open up our team user controller. Okay? So the edit method is normal, it's gonna display the edit form for the team and then the update is going
it's gonna display the edit form for the team and then the update is going to perform the actual work there. Now the view here is called teams users edit. And we need to supply three things to this view. We need the team that we are working with. We also need to supply the list of users, not just the users that are members of this team, but all of the users so that we can add
that are members of this team, but all of the users so that we can add or remove them from the team. But then we also want to know the members that are assigned to this given team. This is actually going to be an array of IDs to make things a little bit easier inside of the view. So that's the information that we want the team is automatically provided here, but we do need to get our users, which we're just gonna
that we want the team is automatically provided here, but we do need to get our users, which we're just gonna fetch all of those. But then we also want the assigned users for this team, in which case we'll get our users, we will pluck the ID from them and we want that as an array. So that's the data that we are going to supply to the view. And if we take a look at the browser, let's refresh here, we will see our users.
And if we take a look at the browser, let's refresh here, we will see our users. There's a checkbox so that we can assign users to the team. We can also pick their role. But notice that you know, nothing is set by default. We know that there are members for this given team, but we're not seeing that here and that's because the view hasn't been completed yet. So let's open up the edits view for the team's users. And it's straightforward.
So let's open up the edits view for the team's users. And it's straightforward. We are iterating over the users to display the list of those users and here's the checkbox, but we want to check the users based upon that assigned value that we have. So the first thing that we are going to do is create a variable called is checked. And this is going to be true if the user ID is in that assigned array.
And this is going to be true if the user ID is in that assigned array. That way we can set the checked property for this checkbox. So all we have to do is check if it is checked. If so, we are going to output the string of checked, otherwise it's gonna be an empty string. So if we take a look at the browser, we can see now that there are some users that are checked and that's great, but we aren't doing anything as far as the roles. So as we are iterating over the users, not only do we need
but we aren't doing anything as far as the roles. So as we are iterating over the users, not only do we need to see if they are already a member of the team, but here we need to see if the role that we are iterating over is the current role for the user. So we can do something like this to where we would have a current role variable and if it's equal to the role that we are iterating over, then we will say that it is selected. Otherwise it's gonna be an empty string.
then we will say that it is selected. Otherwise it's gonna be an empty string. But we of course need to create this current role variable. So we can do that up here where we defined this is checked and the first thing we need to do is determine if the user is a member of this team. Because if they aren't then there's no need to set the current role because they have no role. So if the user is a member of this team, we want to find that user based upon his id.
So if the user is a member of this team, we want to find that user based upon his id. So we'll call first where the ID is equal to the user ID that we are currently iterating over and we want the role data. So we are going to access the pivot data so that we can get the role. However, if they aren't a member of the team, then we are just going to default to member. So if we take a look in the browser now,
then we are just going to default to member. So if we take a look in the browser now, well it doesn't look like anything changed, so let me do a hard refresh and sure enough, everything is working now. So we can see that the users that are members, this one is an owner, that one is an owner, that one's a member, that one's a guest, and then we have another member. And if we wanted to add another member
and then we have another member. And if we wanted to add another member or take one out, then we can do that. But currently we aren't saving that information because the controller method isn't doing anything. So let's change that. First of all, we want to work with just validated information. So we are going to validate the request and there are several things that we need to validate. First of all, we want to validate the users,
and there are several things that we need to validate. First of all, we want to validate the users, that should be an array. Next we have users and then the roles. But we also want to be sure that we have the roles that we would expect, in which case, first of all it's required, but we want to be sure that it's in owner member or guest. But then we also want to get the users that we're assigned, which we have this assigned from our form.
But then we also want to get the users that we're assigned, which we have this assigned from our form. If we take a look at the form itself, we can see that the checkbox has users, the user ID and assigned. So for the users that are assigned, that should be nullable or bullying. And then it's just a matter of setting this information in the database. Now the way that we can do this is by using the relationship object, this many
Now the way that we can do this is by using the relationship object, this many to many relationship and there's a method called sync. The idea of being that whatever we pass to sync is going to sync the database table based upon this data. So it's going to wipe out all of the records in the pivot table for this given team and it's going to set new records based upon whatever it is that we provided. And it looks like this, we start with the user id.
whatever it is that we provided. And it looks like this, we start with the user id. So let's just assume we're gonna set the user ID of one with the pivot data of role set to uh, let's make this a guest. So of course we're hard coding this, but you'll get an idea of of how this works whenever we see it in action. So that finally after everything is done, we will return, we are going to redirect back to basically the same page.
So that finally after everything is done, we will return, we are going to redirect back to basically the same page. The route is teams, users, edit and we will include the status of users updated. Okay? So once again, we're hard coding this just so that we can see how this is going to work and then we will actually make it work with our form. So let's go back. It doesn't matter what we select here,
So let's go back. It doesn't matter what we select here, whenever we save this, we're gonna get an error missing required parameter for the route. Okay, well that, that makes sense. We need to include the team there. So let's go back, we'll resend it and voila. And we can see that the user with an idea of one is now set as assigned to this team and they are a guest. So if we wanted to do the same thing for the user
as assigned to this team and they are a guest. So if we wanted to do the same thing for the user with an idea of three, but we wanted to set the role to let's do owner, we would see the same thing. Except that now we have the user ID of one and the user id of three and they are an owner. So at least we know that we are able to save that information. We just need to save the correct information, which means
that information. We just need to save the correct information, which means that we need to build an array that we are going to pass to the sync method. And then the sync method will do everything that we need from there. So let's start with a sync data, which is going to be an array and we are going to iterate over the validated users as user ID and data.
and we are going to iterate over the validated users as user ID and data. So then we can check if is set data assigned. Then we want to assign this user to the team, in which case we have our sync data. The key is gonna be the user ID and the value is going to be an array with the role set to whatever the data from the request is. So we need a semicolon there. So it's the same idea except that we are building this
So we need a semicolon there. So it's the same idea except that we are building this sync data dynamically so that instead of calling sync and passing in our hard-coded stuff, we will call sync pass in the sync data. And that should work. There's only way, one way to find out. So let's give it a shot. Uh, if we take off the user with an idea of three and pick Jason Stanton and that person can be a member, why not?
and pick Jason Stanton and that person can be a member, why not? And if we save that, then it gives us an error because I used user instead of users so that we will resend the data and sure enough, there we go. But now I want to be absolutely sure that this works. I'll have an owner, we'll have a guest and if we save it, yes, that's working perfect. So now we can manage our teams, we take the information from the form
Assigning Teams to Users33:00
So now we can manage our teams, we take the information from the form and we are syncing that data to the database and that is awesome. Now we just need to do the same thing for the users. But you know, one thing that I have been saying throughout this episode is that what we do for one, we have to do for the other and it, it's mostly the same. We just have to make a few modifications here and there.
and it, it's mostly the same. We just have to make a few modifications here and there. So let's open up the user team controller and we should also open up the edits view for the user's teams that start with the controller. Let's just copy and paste what we have from the edit method in our team's user and paste it to inside of our user teams. This is not confusing at all because it, it's the same thing except
This is not confusing at all because it, it's the same thing except that in this case we are working with a user that we are going to pass teams and we want assigned. The view here though is users teams. So we are going to get the teams, then we are going to get the assigned teams to the user and everything is going to work there. So that, uh, we can go to our view. We need to do the same things
So that, uh, we can go to our view. We need to do the same things because it's essentially the same thing. If we look at the users, which we should see here, yes, we can see the list of teams, we need to be able to check them and select the role. And you know, those values need to automatically be set for us as well. So right here in the four each, you know what we did for the teams, we are going to do the exact same thing
So right here in the four each, you know what we did for the teams, we are going to do the exact same thing for the users. So we're gonna grab this PHP block so that we can put that right here in our for each if it's checked. But in this case we are working with a team instead of a user. So here we have user teams, teams pivot, role is member, great. And then we essentially do the exact same thing
teams pivot, role is member, great. And then we essentially do the exact same thing for is checked. So we will add that to uh, the input element right there. Then we want to do the same thing for the option element. So we will copy that, put that where is the option element, it's right there. And so now whenever we view this in the browser doesn't work, but it didn't work last time did it, we had to control F five and now that works.
doesn't work, but it didn't work last time did it, we had to control F five and now that works. We can see that this user is a member of only one team, which of course we know that. But if we look at some of these others, Russell Hawk is a member of three and we can see that it looks like everything's working. Okay, now we just need to save that information. Let's close the views because uh, it's less cluttered that way, right?
Let's close the views because uh, it's less cluttered that way, right? So we're gonna take the code from the update method from our team user controller. We're gonna paste it inside of our user team controller and just make the necessary changes so that we're not use or working with users. We are working with teams and the roles and assigned everything else. It's gonna be the same there for each validated teams
and assigned everything else. It's gonna be the same there for each validated teams assigned role role here we say user that we are working with so that the teams and we can sync that data with the database. We will reroute to users, teams passing in the user for the routes information. And voila, we are done. At least we should be done. Let's go to the user that has one team and we're gonna add them to this first team.
Let's go to the user that has one team and we're gonna add them to this first team. We're gonna make them a guest. We're gonna save it and it works. Woo, that was a lot. In fact, I don't know if we can recap every, I don't know if I can remember to recap everything, but you know, the key points is that a many to many relationship uses a pivot table. That pivot table defines the relationship between two or even more independent entities like a user and a team.
That pivot table defines the relationship between two or even more independent entities like a user and a team. But it can also contain what we call pivot data, which is data specific to the relationship. And eloquent allows us to create these many to many relationships with the belongs to many relationship class. And not only does it give us that relationship information, but it also lets us use our pivot data and it also has the sync methods so
but it also lets us use our pivot data and it also has the sync methods so that we can save multiple relationships at once. In the next episode, we will look at the has many through relationship, which isn't very common, but it certainly has its uses.
