Defining Model Relationships

In this lesson, we'll learn how to define relationships on our Lucid Models. We'll cover one-to-one, many-to-one, one-to-many, and many-to-many relationship definitions.

Published
Jan 27, 23
Duration
13m 4s

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.

Adocasts

Burlington, KY

🕑 Chapters:

00:00 - Intro
00:30 - Relationship Types
01:30 - AdonisJS Relationship Lookup
02:30 - AdonisJS Relationship Decorators
03:20 - Belongs To (one-to-one)
04:15 - Has One (one-to-one)
05:20 - Relation Configuration Options
07:00 - Belongs To (many-to-one)
07:30 - Has Many (many-to-one)
08:00 - Relationship Model Names
09:30 - Many To Many
11:20 - Pivot Table & Pivot Columns
12:30 - Outro

📜 Transcript:

0:00

so the reason that we saved

0:01

relationships in our models as one of

0:03

the last things here to Define within

0:04

our models is because they kind of work

0:06

differently from the remainder of the

0:08

columns that we've defined so far we've

0:09

defined everything that actually exists

0:11

within our database we all of these are

0:13

valid columns if we were to go look

0:14

within our database they have column

0:15

representations there the actual

0:17

relationship definitions though we're

0:18

going to serve as more of a virtual

0:19

definition and they have lookups that

0:22

look up to the particular IDs that

0:24

define those relationships and the way

0:25

that we Define these varies slightly

0:27

depending on what particular

0:28

relationship type it is so we have one

0:31

to one one to many many to one and then

0:33

many to many within our existing schema

0:35

over here on the right hand side I do

0:36

have those to find out within a key down

0:38

at the bottom I'm going to go ahead and

0:39

expand this out so on the lines pointing

0:41

to the specific relationship definitions

0:43

I've marked it as one to one for one to

0:45

one one to M for one to many M to one

0:48

for minute one and then M to M for many

0:49

to many now the difference between one

0:51

to many and many to one differs

0:52

depending on what side of the

0:54

relationship you're looking on so I've

0:55

pointed all of these in the same

0:57

direction so that all of our one to many

0:59

and many to one are defined as the same

1:01

so here you can see we have a role ID

1:04

pointing to our roles table from our

1:06

users table that's defined as M to 1 as

1:09

many to one instead of one to many

1:10

whereas if we were to go the other way

1:12

then that would become a one to many so

1:14

in terms of those two it's just

1:15

depending on what side of the

1:17

relationship you're starting from and

1:18

pointing to similar to how I have this

1:20

key noting out the different

1:21

relationship pipes here we also need to

1:23

do the exact same thing within our model

1:25

to tell Adonis what type of relationship

1:27

it is that we're working with so that

1:29

they know how to look it up accordingly

1:30

so let's go and collapse this down and

1:32

just like with the actual columns how

1:34

it's differed from camel case to snake

1:36

case there are specific lookups that

1:38

Adonis is going to look for as the

1:40

default naming convention within our

1:41

profile column here we have this user ID

1:43

now the way Adonis is going to look this

1:46

user ID relationship up by default

1:48

whenever we actually Define this

1:49

relationship is this going to take the

1:50

relationship model name and then it's

1:52

going to take the primary key for that

1:53

model and snake case it together so it's

1:56

going to be user underscore ID that it

1:58

would look for because the user model is

2:00

the model that that column is relating

2:02

to and ID is the primary key so here we

2:05

have a match with the actual default

2:06

naming convention for Adonis so the way

2:08

that we would Define this is if we look

2:10

over at our key this is a one-to-one

2:12

relationship our users are always going

2:14

to have one profile and our profiles are

2:16

always going to belong to one user so in

2:19

terms of our Lucid models we're going to

2:20

want to Define both sides of those

2:22

relationships so that we have both sides

2:23

to work with you can Define just one

2:25

side if you know that there's one side

2:26

you're never going to work with but I

2:29

prefer to Define both because you never

2:31

know when it might come in handy later

2:32

down the road and the way that we Define

2:33

these relationships just like with all

2:35

of our column definitions is via

2:36

decorators so there's a different

2:37

decorator per relationship type that we

2:40

have within our model in a really great

2:42

spot to find all of the different

2:43

decorators for the relationships is

2:44

within the documentation if you go into

2:46

references the database scroll down on

2:48

the left hand side you'll see

2:49

relationships here and you'll see has

2:50

one has many belongs to many to many and

2:53

then has many through now we're not

2:54

going to be focusing on as many through

2:55

quite yet we'll save that for a later

2:56

point in time but with our specific

2:58

schema we do have a relationship for

2:59

each one of these four has one has many

3:02

belongs to a many to many which one to

3:03

use here in your particular use case can

3:05

be kind of confusing for people

3:06

especially if you're not used to the

3:08

terminology here the easiest way to

3:09

remember it here if we dive back into

3:11

our profile if the column actually

3:13

exists on the model in most cases that

3:16

will be a belongs to because our profile

3:18

belongs to the specific user ID so we

3:22

can Define this within this model here

3:24

by doing at belongs to and then we

3:26

provide in the actual model that this is

3:29

related to so we do this as a callback

3:31

function let's import our user model

3:33

here then just like all of our other

3:35

columns here we want to do public give

3:37

this relationship a name we can do user

3:39

and then the type for this is going to

3:40

be belongs to let's open this up type of

3:44

and then the user so if I scroll up just

3:46

a little bit here you can see we have

3:47

our user ID on our profile model now we

3:50

also have a user relationship which

3:51

serves as kind of a virtual

3:53

representation of what a actual user Is

3:55

So within our profile model we already

3:57

have everything done this is our

3:58

perfectly valid relationship definition

4:00

all we need to do from here is query and

4:02

work with it but we do want to go on the

4:04

inverse side of this relationship on our

4:06

user and also Define it there because we

4:08

don't know whether or not we need to

4:09

populate the profile from the user side

4:10

or from the profile side so we want it

4:12

to be available from both sides so that

4:14

we can work with it either way so let's

4:15

jump over to our user model scroll down

4:17

since there's no profile ID on the

4:19

actual model here this isn't going to be

4:20

it belongs to it's going to be a has one

4:22

because a user has one profile so we can

4:24

do at as one provide this a callback of

4:27

type profile and this will point the

4:29

actual relationship to our profile model

4:30

do public profile and then we want to

4:33

define the type here as has one type of

4:35

profile and so now we have both sides of

4:37

the relationship defined so whenever we

4:39

go to query this we can query a user

4:41

with a profile or we can query a profile

4:43

with its attached user either way it

4:45

works so there's an example of a

4:47

one-to-one relationship definition

4:48

within adonisjs on one side we have a

4:51

has one and then on the other side we

4:53

have a belongs two because this is the

4:55

side that has the actual referencing of

4:57

the ID for the relationship and the way

4:58

that the Donis is going to look up up

5:00

the ID value here is based off of the

5:02

relationship definition so it's going to

5:03

take the model and it's going to lower

5:05

case that and it's going to concatenate

5:07

that with the primary key of that

5:08

related model so in this case it would

5:10

be user underscore ID and that's how it

5:12

would look up the column definition

5:13

within the actual database and the

5:15

actual column value for our user ID up

5:17

here is the exact same it's user

5:18

underscore ID so the two match up

5:20

perfectly in the case that they didn't

5:22

there is that additional option set

5:23

within this belongs to has one has many

5:26

and many to many all of them have it

5:28

they do very differently depending on

5:30

what type of relationship definition it

5:31

is but they all have this additional

5:33

option set where we could define

5:34

specific column values in case anything

5:36

doesn't match up one to one with the

5:38

default naming structure of Adonis and

5:40

again the best place to find all

5:41

different relationship options is within

5:43

the documentation within the reference

5:44

under database you can scroll on down to

5:46

decorators where you have all of the

5:48

different decorators that we have

5:49

defined here so if you look at has one

5:51

you can see right here we have our has

5:54

one example with a profile if we scroll

5:56

down we have all of the different

5:57

options that we can provide into this so

5:59

we have the foreign key the local key

6:00

serialize as and on query callbacks that

6:03

we can Define on this particular

6:04

relationship the foreign key and local

6:06

key are the two different options that

6:07

you have in this particular relationship

6:09

definition when it comes to how Donna

6:11

should look up what particular column it

6:13

should find for a particular

6:14

relationship so you have form key for

6:16

one side of the relationship and local

6:18

key for the other side of the

6:19

relationship so you can Define the two

6:20

different columns that you should use

6:21

for the relationship look up there and

6:23

then you have serialize which changes

6:25

the actual column name and how it's

6:26

serialized the same as with the column

6:28

decorator then you also have on query

6:30

which allows us to Define additional

6:32

always existing query definitions

6:34

whenever we go to query the actual

6:36

column and this is really powerful and

6:38

allows us to Define specifics if we want

6:40

to define a relationship specifically

6:42

for a set type so say maybe with our

6:44

many many relationship with our posts

6:45

and our topics if we always wanted our

6:48

topic to query public posts we could

6:51

Define that within the on query images

6:52

always happen anytime that we query our

6:54

posts from our topic cool so we have one

6:56

relationship definition done let's go

6:58

ahead and move on to some of the others

6:59

how about we do a mini to one next let's

7:01

do our user and our role so let's go

7:03

back into our user model and this is

7:05

another case where we have a specific ID

7:07

on the user model now despite this being

7:09

a many to one instead of a one to one

7:11

since the ID is still on this model it

7:13

still belongs to definition so we can

7:15

scroll down to the bottom do at belongs

7:17

to provide us a callback to our role

7:20

model public role and the type will be

7:22

belongs to type of role so there's one

7:24

side let's jump over to our role model

7:26

and on this side since a role can have

7:28

many users this would be a has many

7:30

relationship so we could do at has many

7:33

provide this a callback with the user

7:35

model since this is the relating model

7:37

do public users has many type of user

7:41

and there we go there's our many to one

7:42

relationship example done now we do have

7:43

a couple more of those within this

7:44

project so let's go ahead and Define

7:45

those out before we move on to many to

7:47

many so we also have a post that belongs

7:48

to many users so let's go ahead and

7:50

Define that out so let's jump into our

7:51

post model here again this is another

7:53

one where it has that ID on it so in

7:55

this case it's going to be belongs to so

7:57

we can scroll down to the bottom do at

7:59

belongs 2 provide that our user model

8:01

public user belongs to type of user now

8:06

in this particular use case whenever we

8:07

go to add our user onto our posts via

8:09

querying it may not make complete sense

8:11

to us what exactly the user is so it

8:13

might make more sense to name this

8:14

something different something more

8:16

meaningful for our relationship name

8:17

here so since we actually have the model

8:19

bound to the relationship the model is

8:21

what's going to be used to find that

8:22

actual column name and the actual name

8:24

of the relationship or free to name

8:26

whatever we desire so here instead of

8:28

user we're free to name this something

8:29

like author if we so wish and whenever

8:31

we go to query that later on we can use

8:33

that reference name of author in order

8:35

to preload our author onto our posts in

8:38

which case that might be more meaningful

8:39

than preloading a user onto a post

8:41

instead we can preload an author so you

8:43

have that option available to you as

8:45

well so we can go ahead and give that a

8:46

save jump over to the other side so we

8:48

have that user side and over here our

8:50

users can have many posts so this would

8:52

be a has mini so we do at has many host

8:55

public posts has many type of and there

8:59

we go there's that relationship

9:00

definition done now on our post we do

9:02

have one more additional belongs to and

9:04

that's for our state ID so we can go

9:05

ahead and Define that up as well so this

9:07

would be at belongs to state public

9:10

State belongs to type of state and we go

9:13

ahead and jump into our state model and

9:15

Define that relationship there as well a

9:17

state can have many posts so this would

9:19

be a at has many post public posts as

9:23

many type of posts there we go and now

9:27

all that that leaves us is our post to

9:28

topic many to many relationships so for

9:30

this specific relationship we do have

9:32

this post topic pivot table that we'll

9:34

want to go through in order to bind this

9:36

relationship together and if you

9:37

remember there's a specific many-to-many

9:39

decorator that allows us to do that

9:41

without needing to define a specific

9:42

model for that post user table so let's

9:44

jump into our post side first and let's

9:46

get this to find out so we have an at

9:48

many to many just like all of the others

9:51

we wanted to find this to the particular

9:52

model that is bound to on the inverse

9:55

side of the many to many skipping over

9:56

that pivot table so in this case it

9:58

would be our topic scroll up a little

10:00

bit here this would be public topics

10:01

Mini 2 mini type of topic so really

10:05

looks the exact same as all of the

10:06

others but whenever it comes to the

10:08

actual option set there is a little bit

10:09

more to it so let's dive into the

10:10

documentation set take a look at it so

10:12

you can go back within the reference

10:13

database scroll down to the orms section

10:15

where decorators is come over on this

10:17

page to many to many and you can see

10:19

each one of these options here along

10:21

with a definition so since there's two

10:22

different sides to this relationship

10:23

you're going to have two different sets

10:25

of keys you can Define so you have the

10:27

four in which is one side and then you

10:28

have the local which is the other so

10:30

pivot foreign key is going to be one

10:32

side pivot related form key is going to

10:34

be the other then you have local key and

10:36

related key which are two different

10:37

sides as well and if you ever get

10:38

confused or needed an example whenever

10:40

you're looking this up on the Fly you

10:42

can get within guides scroll down to the

10:43

orm section go underneath relationships

10:46

come over here on the right hand side

10:47

the mini the mini and you'll get an

10:49

example so here within the example you

10:50

have users and skills Bound by a skill

10:52

user pivot table if you scroll down just

10:54

a brief bit it goes over what each one

10:56

of these Keys represents with that

10:57

example so just know that that does

10:59

exist exist on the documentation if you

11:01

ever get confused on which is which

11:02

there a great way to bypass all of that

11:04

is just use the default naming

11:05

Convention of Adonis because that's what

11:07

we've done here and we can just leave

11:08

this relationship definition as is and

11:10

everything will work out of the box with

11:12

no issues but if you do ever need to

11:13

provide those in here just provide a

11:15

secondary argument of those relationship

11:17

options and they'll work just fine there

11:19

are a couple of additional ones that we

11:20

haven't covered yet called pivot table

11:21

and that's going to be the table name of

11:23

the actual pivot table so in our case

11:25

it's going to be post topic and the way

11:26

that it'll find that is just binds two

11:28

model names together and snake case and

11:30

that's the default naming convention

11:31

that we've gone with here so we don't

11:32

need to Define that here but there is an

11:34

additional one of pivot columns and

11:36

these are columns that will be included

11:38

from the pivot table anytime that we

11:39

query these relationships so in our case

11:42

we do have one of those we have that

11:44

sort order and the way that we can

11:45

Finance this via an array and we just

11:47

need to define the actual column name

11:48

there to include with it so if we want

11:50

that included every single time that we

11:51

read these two relationships we want to

11:53

include that on both sides of that

11:54

relationship so that it will be

11:55

automatically included you can also omit

11:57

that here and Define to include it in

11:59

any particular one query on the query in

12:01

itself so you have the two different

12:03

options there on how to include those

12:05

intermediary table columns in our use

12:06

case I'll go ahead and leave it here so

12:08

that you know that that does exist so

12:09

let's go and jump back over to the

12:10

opposite side here so we have our post

12:12

done now we need to do our topic side

12:13

and this is just going to look the exact

12:15

same everything's just going to be flip

12:16

flop so we have our mini to mini this

12:18

will be bound to our post public posts

12:20

mini to mini type of post again we also

12:24

have all of those same options available

12:26

here everything is just flip-flop

12:27

value-wise but we do want to Define that

12:30

pivot columns as sort order so that's

12:33

available anytime that we query and

12:34

there we have it so all of our

12:35

relationship definitions are done we're

12:37

good to move on to crud work in the next

12:39

lesson if you enjoyed this lesson or you

12:41

learned something new please consider

12:42

hitting the like button down below and

12:44

subscribing future lessons just like

12:45

this one as I just stated we're going to

12:47

move on to credward next with our

12:49

different models and then we'll move

12:51

into relationship cred work after that

12:52

so thanks for sticking around everybody

12:54

I'll see you all in the next one

12:57

[Music]

Join The Discussion! (0 Comments)

Please sign in or sign up for free to join in on the dicussion.

robot comment bubble

Be the first to Comment!

Playing Next Lesson In
seconds