Transcript
-
So the remainder of the relationships work relatively similar to our one-to-one relationships. The only difference is they have their own decorators
-
and options sets we can provide into them. So let's go ahead and jump into our user model. And on this model, we have a role ID. As we learned in our one-to-one lesson,
-
anytime that the role ID or relationship ID is on the model that we're working with, we'll want this to be defined as a belongs to because that relationship belongs to the model
-
that we're working with. So let's scroll down to the bottom and we already know how this one works. So we'll do @belongsTo, provide that a callback function that returns back our role model.
-
Declare role as belongs to type of role, just like so. So our user here can only have one role.
-
However, our roles can have many users bound to them. So on our role side, this, instead of being a has one,
-
would instead wanna be a has many because any one role can have many users. We'll return this back our user model instance inside of its callback,
-
and we will declare and call this users has many type of user. We're gonna get a red squiggly again because that did not auto import with the type declaration on it.
-
So we'll add that in and now everything's happy. The options for our has many are relatively similar to our has one. We're gonna have a local key and a foreign key.
-
The local key is going to be the relationship key for the model that we're currently on. So that would be our roles ID. So we could provide that in there if we wanted to.
-
And the foreign key would be the relationship ID on the model that we're relating to. So our user model, if we scroll down, that would be our role ID.
-
So we could provide that in there if we wanted to. Again, though, for these, we are using the defaults. We already know that our local key is definitely ID, so we can get rid of that.
-
And our foreign key will take our roles name plus its primary key of ID. So that would be role ID, concatenate them together in a camel case fashion,
-
which would result in role ID as we have it here. So we can get rid of that one there as well and just use the defaults. Cool, so that's how you define one to many or many to one relationships,
-
depending on what side of the relationship you're looking at it on. If you're looking at that from our user side, our user can have one role, so that would be a many to one.
-
We have many users going to one particular role. If we're looking at that from our role side, we have one role pointing to many users. So that would be a one to many,
-
many to one, one to many. And we have that going on in a couple more places as well, primarily on our movie, where we have our status ID, writer ID and director ID.
-
Since our movie model contains the IDs for all three of these relationships, all three will be defined as a belongs to. So we can scroll down to the end of our column declarations,
-
but before our query scopes and define them here. So at belongs to, we'll start with our movie status. So we'll do movie status,
-
whoops, not the enum, movie status, our model. There we go, declare. And you can either name this movie status if you wanna be verbose, or you could just name this status,
-
belongs to type of movie status. Again, the actual name that you give the column doesn't matter so much, especially in terms of defaults for the relationship.
-
That's the model names and the primary keys that use those. So we need to specify this as a type import yet again. So let's scroll back up, add type there, and scroll back down. And for this one,
-
we do need to change the options a little bit because we're not actually making use of the Lucid defaults. So our model name is movie status and its primary key is ID.
-
So what this would be expecting for our foreign key by default would be movie status ID. However, if we scroll up,
-
we'll see that we're actually calling this just status ID. So we're not making use of the default for this relationships naming convention. And so we will need to specify that as just status ID here
-
so that Lucid knows the correct column to use when matching this relationship together. But with that set, we are A-okay with our belongs to for our status.
-
We can give this a copy and a paste one time. And now let's do our director ID. So that uses our Cinest model and the column name here will be our director.
-
And again, this will be our Cinest model. Now, yet again, we're going to need to define the foreign key for this relationship because AdonisJS's default will be expecting Cinest ID
-
as that's our model name. And that model's primary key is ID. However, we have this relationship called director ID. So we're gonna wanna give that column there a copy,
-
jump back down to our relationship definition and paste that in. So now Lucid knows to use our director ID anytime that we're trying to query our director from our movie.
-
We can give this one here a copy and a paste yet again for our writer. Now our writer also uses the Cinest model, but we'll want it to be called a writer for the column name.
-
And it's foreign key is not director ID, but instead writer ID. So as you can see, using the relationship arguments, this is how we can go about using one model for multiple different relationships,
-
depending on the particular foreign key that we provide, in this case for the belongs to relationship. Remember belongs to is the one where this is a little bit backwards and the foreign key is on the same model we're working with.
-
With all of the other ones, foreign key is the related models ID for the relationship. Cool, so we should have all three of these set for this side of the relationship. Let's jump over to our movie status
-
and take care of that side. Again, any one movie status can have many movies bound to it. So this will be a has many here as well. We'll return a callback that returns back our movie model
-
and declare movies as type has many type of movie. And we need to fix that type import once more, just like so. And again, since we're working with has many now,
-
our movie status model, plus its primary key of ID is not the correct default foreign key that we would expect for this relationship. So we need to provide in that foreign key
-
for this relationships definition, and that will be our status ID column on our movie model. Cool, so that one there should be good now as well. Let's jump over to our Sinus model.
-
And we're gonna have a couple for this one. So let's scroll down. We'll do this underneath our computed column. And we're gonna have both a writer and director ID pointing to our movie.
-
And any one Sinus can either write or direct multiple movies, so both will be a has many. So add has many there, provide a callback function pointing to our movie model.
-
Scroll down a little bit. Let's declare. For right now, let's just call this movie. And then the type will be has many type of movie. And let's go up and fix our type import real quick.
-
Okay, and let's give this a quick copy and a paste. So we're gonna have one for our director and one for our writer. We already know that we need to provide the foreign key
-
to specify which is which here. So foreign key, this one will use our director ID on our movie model. And this one will have a foreign key
-
pointing to our writer ID on our movie model. And now we can specify whatever name we want to appropriately assign that this relationship
-
is for our Sinus directed movies. And this relationship is for our Sinus written movies. So for that, we could do something like movies directed and movies written.
-
But again, you can name these whatever you want for the actual column names. Okay, so it should be all set with our relationship definitions on our models. Now we need to add in fake data for both of these
-
so that we have something to work with.
Defining One to Many Relationships with Lucid Models
We'll learn how to define one-to-many and many-to-one relationships using Lucid Models. We'll also learn how we can specify the columns that should be used for a relationship, allowing us to use one model for multiple relationships.
Join the Discussion 4 comments
-
Hi Tom, is there any way to do a polymorphic relationship? Or how would you accomplish having a model (e.g. Comments) that could belong to more than one model type (e.g. Movies and Cinests)?
1-
Responding to cbernard
Hey cbernard! Currently, there isn't a way to do polymorphic relationships with Lucid support. There are a couple of solutions you could use, maybe others as well.
Define a relationship column per relationship. If you only have a few tables needing the polymorphic relationship, you could just define an id column for each individual relationship, for example on
comments
you could have a nullablemovie_id
and a nullablecineast_id
column.
This is the approach I use for comments here on the Adocasts site.You could create a pivot table per relationship, for example, a
movie_comments
andcineast_comments
. In this case, don't think of it as a many-to-many, but rather a has many with an additional has one step. movie → has many comments (movie_comments) → has one comment (comments).
Hope this helps!
1-
Responding to tomgobich
-
Responding to cbernard
-
-