00:05
All right, so we already have some form of relationship between our movies and our Cineasts via our writer and director IDs.
00:11
Both of these point directly to our Cineasts IDs, and we have that relationship mapped for each as a one to many or many to one,
00:18
depending on what side of the relationship you're looking at it on. However, things get a little bit interesting because we also get to introduce pivot tables, crew movies, cast movies,
00:27
which are in charge of binding individual cast members. And individual crew members via our movies and cynist tables as well.
00:34
And that's where the many to many relationship type enters into the frame. In terms for actual models, we're not going to have a model specifically for the pivot tables.
00:42
Instead, we're going to use the relationship bindings to define what the pivot tables are, and any additional intermediary data columns that we
00:50
might want to pluck along with that relationship. In terms of our tables, that's going to be their title or their character name, in addition to the sort order.
01:00
So defining a many to many relationships relatively similar to the others. We just have a decorator and a type that informs Lucid what the relationship is and what type it is.
01:09
So if we scroll down a little bit here to give us some extra room and type @many2many, there we go. We can auto import that by hitting tab.
01:17
Now for the model that we return to the callback function here, we want to return back the model for the exact opposite side of the many to many relationship. So for that, we would want to go from our movies,
01:26
which is the model we're in right now, through either our crew movies or cast movies pivot tables into our underlying cynist table.
01:33
Which then means that we would want to reach and return back our cynist model, as that is the model for the exact opposite side of this many to many relationship.
01:43
Then we can declare, right now, let's just go ahead and call this cynist. We're going to have two because we have one for our crew movies and one for our cast movies as well.
01:51
So we'll take care of individualizing those once we get this fully defined. Then we'll have our type of many to many. We can hit tab to auto import that as well.
02:00
Type of our cynist model. All right, so if you're thinking ahead, the way that we can discern what intermediary table this relationship
02:08
should use, as well as the pivot columns that we want to plot with it, is by providing additional column options for our many to many relationship. Similarly to how we're doing with our writer and
02:17
our director in our one to many relationship. However, the options for the many to many are drastically different than all of our other relationship types.
02:26
So instead of just foreign key, we now have two different options. So if we type out foreign key or just foreign here, we're going to see autocomplete options for pivot foreign key and pivot related foreign key.
02:36
If we bring back up our diagram here, remember we're on the movies model at present. So we'll be referring to things as though we're coming from this side of the relationship.
02:43
Our pivot foreign key is going to be a pivot tables key column pointing back to the model that we're presently on.
02:50
So since we're on our movies model, the pivot foreign key would be our movie ID on either our crew movies or cast movies pivot tables.
02:58
So let's do pivot foreign key movie_id. Since we don't have models for our pivot tables to refer off of,
03:07
we need to provide the column name as it's defined in the database for these foreign key values. And in our database, we're using snake case.
03:15
So we'll want to provide it as snake case for this particular relationship definition. Then that means our pivot related foreign key is going to be
03:24
the key column on the pivot table or the related model. Since we're on our movies model at present, the related model is going to be our cynist model.
03:32
And the pivot related foreign key then would be our cynist_id column on either one of our two pivot tables.
03:38
So for our pivot related foreign key, we can provide cynist_id just like so. There are two other columns that we can relate to as well.
03:47
We can specify both of the ID columns for the parent model, which would be the movie model which we're presently on, and the related model as well, which would be our cynist model.
03:56
So for those, that would be our local key for the parent ID column, which would be our movies ID column, and then related key,
04:03
which would be the ID column on our cynist model. Now, if you're following along so far, and we stop for a second here and
04:10
compare what we have to what's defined inside of our database, you'll see, okay, the two IDs match up one to one, so we can go off the default for
04:17
both our local key and related key for these. Our pivot foreign key is movie_id. On both of our models, we are using movie_id for the naming for
04:26
our crew movies as well as our cast movies. So for both of those, we can use the default for our pivot foreign key as well. And that's also true for our pivot related foreign key,
04:34
which is using cynist_id for both of these relations as well. In turn, meaning we're okay to use the defaults for all of what we've defined so far.
04:43
So we can go ahead and get rid of them to remove that clutter. However, we have strayed pretty darn far from Lucid's default naming convention for our pivot table.
04:50
By default, Lucid's going to concatenate together the two model names for the relationship, which would be our movie and cynist models with an underscore. So it's gonna make them snake case.
04:59
So it'll be movies_cynists, and then it's going to sort them. So instead of movie_cynist, it would be cynist_movie.
05:07
In our case, if we bring our relationship back up, we have two variations of this relationship. So we have crew movies, and we have cast movies.
05:15
So not only will we not be using the default because we've also pluralized these names, we have crew_movies rather than just crew movie.
05:22
But we've also deviated from our cynist model name so that we can have two different variations of this relationship. So for both of these, we will need to define pivot table option.
05:32
And this is how we're going to dictate which pivot table we're using for the actual relationship definition and allow us to have two different versions of this relationship between our cynist and
05:41
our movies. So our first pivot table, we're gonna call our crew movies. And we can declare the actual property name however we'd like.
05:49
So we could just call this crew if we wanted to. However, I would like to have it pluralized so that we know just by the name that it is an array.
05:56
So let's call this crew members. Let's give this a copy and a paste because we also need a representation of
06:03
this relationship for our cast movies pivot table as well. And the name for this one, we can call our cast members.
06:11
Everything else for these two relationships will remain the same. Okay, so before we move any further, let's go ahead and re-reference our pivot tables as we have them defined inside of pgAdmin.
06:19
So we have our crew movies pivot table right here. We can take a look at the columns for this. And in addition to our two relationship columns, our cynist_id and
06:27
movie_id, we have additional information provided on this table, like our title and sort order. And if you care about them, they're created at an updated.
06:34
I believe we have the exact same setup on our cast movies as well. So if we take a look here, yep, it looks relatively similar. So we have our two relation columns. And then instead of title, this is character name.
06:44
And then we also have sort order that we added in later on down here. Okay, so let's hide pgAdmin back away. For those additional columns that we have defined on our pivot table,
06:52
we can either eagerly define on our model that we always want that information included whenever we load in the relationship. Or we can lazily load that in anytime that we specifically need it
07:02
from the query builder. So that we can cover both instances of that, let's define it eagerly for just one, and then we'll cover how to lazily load it in the other.
07:11
So on our cast members, let's go ahead and define a pivot columns option. For this option, all that we need to do is provide an array of the actual column
07:19
names, and AdonisJS will provide them anytime that we load in this particular relationship. So our cast members was the one that had, I believe,
07:27
character name as its information column, and then it also had a sort order. Now, although we don't have models for our many to many relationships,
07:36
we can actually have Lucid still maintain our created at and updated at timestamps automatically for us. So let's go ahead and open up our browser and jump into the documentation.
07:44
Right here, I'm at lucid.adonisjs.com, and we've gone down to the model section, relationships, many to many, specifically the pivot table timestamps section.
07:52
There is a column here called pivot timestamps that we can set the true. When we set this to true, Lucid is going to automatically set and
07:59
update the timestamps on insert or update appropriately for our timestamps. It will also automatically convert them to a Lux and
08:06
date time as we have on our other models when we're working with date time values. Additionally, had you named those two columns anything different,
08:15
you can specify those two columns by providing an object into the pivot timestamps with the created at column name provided as well as the updated at column name.
08:22
And if you just want one or the other, you can provide false for whichever one you don't want. So for both of our relationships here, I think it would be great to go ahead and have Lucid automatically take care of that for us.
08:32
So let's go ahead and set pivot timestamps to true for both of these. Jump down to here, pivot timestamps to true like so.
08:39
So now anytime that we insert through our model relationship for our cast or crew members, those pivot timestamps will automatically be added or
08:48
updated appropriately for the action that we're taking. So that's officially one side of our many to many relationship defined. The other side just needs to pretty much mirror the relationship definition.
08:58
So if we copy what we have here, jump over to our Sinus model, scroll down to where we have our relationships defined for our movies written and movies directed. Underneath there, we can go ahead and paste this in.
09:07
We'll get red squigglies because our many to many is not imported. We can just retype that, hit tab to auto import and retype this one and hit tab to auto import that as well to take care of that.
09:17
And since we're now on our Sinus model, we no longer want to relate this to our Sinus model, but rather our movie model. So we'll want to copy that and paste that in for
09:26
the model for both of these relationships as well. And then lastly, we may or may not want to update the name. Whenever we load this in from our Sinus side,
09:33
we probably want to refer to it as their crew movies and cast movies or something similar to that. So I think that's good enough for this use case.
09:41
So we'll go ahead and do crew movies here, just like so, and cast movies for this one, just like so.