What Is A Model?

In this lesson, we'll delve into AdonisJS Models learning what they are, what they represent, how to create them, what we can do with them, and more.

Published
Dec 22, 22
Duration
12m 44s

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 - What Is A Model?
00:40 - Database Query vs Model Query
02:30 - Model Creation Flags
03:35 - Model Features
04:50 - Creating Our First Model
07:00 - Column Decorator Arguments
08:37 - Default Column Naming Convention
10:15 - Converting Migrations To Models
12:20 - Outro

📜 Transcript:

0:00

with adonisjs there's two different ways

0:01

we can actually communicate with our

0:02

database so you have the database module

0:04

and then you have models now models

0:06

serve as the recommended interface to

0:07

actually communicate with your database

0:08

and then falling back to the database

0:10

module anytime that models can't fill

0:12

the void that you're looking for now

0:13

models follow the active record pattern

0:15

meaning that they're going to serve as

0:16

encapsulations for the database

0:17

interactions that we'll be doing and

0:19

they'll provide back objects or classes

0:21

that are type safe for us so a model is

0:23

going to serve as a representation of an

0:25

actual database table so for the most

0:27

part we're going to want one model per

0:28

table within our database with the

0:30

exception of those many to many pivot

0:31

tables in the long run by utilizing

0:33

these models we're actually going to

0:34

save ourselves a ton of code so if we

0:36

actually take a look here adonisjs has

0:37

an example on their documentation here

0:39

so here's an example of what a query

0:41

looks like without models so you query

0:43

it from the database using the database

0:45

module and then you represent what table

0:46

you want to pick from selecting The

0:48

Columns then you get back all of those

0:50

users then anytime that you query those

0:51

users for display you're going to need

0:52

to Loop over them to convert any

0:54

database values to display safe values

0:56

so in this example here they're looping

0:58

over the users getting a single user

0:59

within this call back here then they're

1:01

converting that user's date of birth

1:02

using luxem date time they're ingesting

1:05

that date of birth and then changing its

1:06

format with models this is vastly

1:08

simplified and we only need to perform

1:09

this conversion once and adonisjs will

1:11

recognize we want to do that every

1:13

single time so if we actually take a

1:15

look at their example here we have a

1:16

user model which is represented by a

1:18

class that extends a base model in this

1:20

column decorator represents the actual

1:21

property that is decorating is a valid

1:24

column within our database table off of

1:26

the column decorator we're chaining off

1:27

a date method the State method actually

1:29

instructs Lucid to actually take that

1:31

value convert it from that date or date

1:33

time string from the database and

1:34

convert it into a lux and date time

1:36

object for us automatically no

1:38

additional checks needed on our part now

1:39

within the State method we're actually

1:41

providing an option to serialize the

1:43

serialize method will run anytime that

1:44

our user model is actually serialized so

1:47

really anytime that we're passing it

1:48

from Adonis to outside the Adonis

1:50

ecosystem this could be returning it as

1:51

an API response or it could be returning

1:53

it from Edge to our front end code base

1:55

and down here they do have an example of

1:57

how to actually go about serializing

1:59

this manually as well but this method

2:00

will run anytime that that happens and

2:02

within this method we're provided the

2:04

value for the column and we can actually

2:05

take that value and convert it using any

2:07

Lux and date time method that we might

2:09

want to choose in this case they're

2:10

using two format to change the format

2:12

value as they were showing in the

2:13

previous example so here's a look at the

2:15

two side by side the model one will run

2:17

every single time that we query using

2:19

our model this top one will need to

2:21

execute any time that we query our users

2:22

on our own so that's one awesome level

2:24

of abstraction that lucid provides for

2:26

us that we don't need to worry about we

2:28

set it once and then we can forget about

2:29

it now whenever it comes time to

2:30

actually creating our models the acli

2:32

comes in very handy you can see here we

2:34

can use the make model command to easily

2:36

create a model by just providing in the

2:38

name so in this case user and that will

2:39

create the model for us within app

2:40

models and it will call it user.ts as

2:42

with everything else in Adonis there is

2:44

naming normalization going on here since

2:46

models generally represent a single

2:47

record for a table they're going to be

2:49

singularized so if you were to provide

2:51

users as the name adonisjs Will

2:53

normalize that to user automatically for

2:55

you but in addition to just creating the

2:56

model you can also pass in additional

2:58

Flags to create other things for the

3:00

model automatically so you can see here

3:02

we can provide in hyphen M to create a

3:04

migration automatically at the same time

3:05

we're creating the model there's a

3:07

hyphen f to do the exact same for a

3:08

factory factories are used so that we

3:10

can easily create loads of test data for

3:12

the model out of the get-go that's

3:14

provided an instance of Faker within

3:15

there so you can fill those up with a

3:17

bunch of fake data there's also a hyphen

3:19

C which isn't in this documentation set

3:20

here but that will create a controller

3:22

for the model as well and you can mix

3:24

and match those in any set that you

3:25

might need so you can do hyphen MC to

3:27

create a migration and a controller you

3:28

could do hyphen MF to create a migration

3:30

in a factory you can do hyphen MFC to

3:33

create a migration Factory and

3:34

controller all at the same time in

3:35

addition to the things that we've just

3:36

talked about models can also do loads of

3:38

other things for us including allowing

3:40

us to Define query Scopes allowing us to

3:42

extend our own methods off of it so that

3:44

we can easily reach for stuff that can

3:45

be both class and instance level methods

3:47

so we can either perform it in a broad

3:48

sense by doing it as a class method or

3:50

we can perform it on instance method to

3:52

do it for a single record within our

3:53

database and then as we saw a moment ago

3:55

with the serialize method here you

3:57

there's also other methods that you can

3:59

do off of this there is consumed so that

4:00

you can change how it's actually

4:01

consumed straight out of the database

4:03

there's prepare so you can change how it

4:04

goes into the database then there are

4:06

hooks that'll actually allow you to

4:07

chain in particular events that are

4:09

happening on a Model Ruby Scoops which

4:11

come in handy with the query Builder

4:12

which allow you to just pack a level of

4:14

different query statements into one

4:16

specific method there's the query

4:17

Builder as a whole which is the same as

4:19

the database query Builder but there's

4:21

also a lot of other methods available on

4:22

the model query Builder that aren't

4:24

available on the database query Builder

4:25

like preloading relationships that allow

4:27

us to take our querying just a step

4:29

further so that we don't need to

4:30

actually join everything anytime that we

4:32

want a relationship and in order to do

4:33

that we also need to Define our

4:35

relationships on the model as well which

4:37

just provides a universe of different

4:39

functionalities for us so we're going to

4:41

be spending the next several lessons

4:42

focusing specifically on models and all

4:44

of these things that we've just talked

4:45

about taking a look at them one by one

4:46

and we're also going to step through the

4:48

different crud actions as well but we've

4:49

spent a lot of time here looking at the

4:51

documentation what we need to do now is

4:52

actually create our models within our

4:54

project so if we jump back into our

4:55

project here we have our two migrations

4:57

our roles and users migrations now at

4:59

this time there's no automated process

5:01

to take this migration definition and

5:02

just convert it into a model it's a

5:04

manual process at present but it's

5:06

actually relatively easy if we utilize

5:08

some Visual Studio code options at our

5:10

disposal and one really cool thing to

5:12

have installed within Visual Studio code

5:13

is the adonisjs extensions pack this

5:16

provides you not only a number of

5:18

different things off to the toolbar that

5:19

I have hidden off on the left hand side

5:21

here or you might have it off to the

5:22

right hand side like being able to

5:24

visualize your routes and a number of

5:26

other things but if we hold command or

5:28

control shift p you'll see that we also

5:30

have all the ace commands available at

5:31

our disposal here one of which is this

5:33

make model so we can go ahead and click

5:35

on that provide in the model name so

5:37

let's do roll first so we can provide

5:39

enroll hit enter there then it'll step

5:40

through those flag options for us so it

5:42

will ask us first if we want to generate

5:43

out a migration for this model we

5:45

already have one here so I'm going to

5:46

hit no then it will ask us about a

5:48

controller we don't need one for roles

5:50

so we'll hit no on that as well and

5:51

it'll ask us about a factory we've

5:53

already generated out our rules within

5:54

that migration file using this defer so

5:57

we can go ahead and hit no on that as

5:58

well now convert if you don't want to

6:00

use that you can also jump into your

6:01

terminal go into your project and write

6:03

out the command manually so you can do

6:04

note Ace make model and call that roll

6:07

if you execute that it'll skip over it

6:09

since I've just created it but if you

6:10

don't have it created then it will go

6:11

ahead and make it for you so you'll see

6:12

a couple of things here first we have

6:14

that column decorator that we saw

6:15

previously on the documentation this

6:17

represents that the ID created at and

6:19

updated at are valid columns within our

6:21

database which if we were to take a look

6:22

right here jump into our roles you can

6:24

see we do indeed have an ID created at

6:26

an updated app but we also have a name

6:28

and description that we need to add in

6:29

here as well so what we can do is Define

6:32

these as columns so we can add in that

6:34

column decorator to find it as a public

6:35

property Define the actual column name

6:37

and then Define its type within a

6:39

typescript save type so it's not going

6:40

to be one to one with the actual type

6:42

that's in the database but it's going to

6:43

be close and it's going to be a

6:44

typescript representation that you use

6:45

so as you can see our ID is going to be

6:47

an integer within the database but

6:49

within our model it's a number and then

6:50

in addition to name we also have an at

6:52

column public for our description this

6:55

too is a string and there we go we have

6:57

our first model up and running and ready

6:58

to go already now there's a few things

7:00

that we haven't discussed here yet that

7:01

are going on within this particular

7:03

model so first within column we're

7:04

providing in an is primary true as an

7:07

argument to The Decorator as you might

7:09

have guessed this does actually

7:10

represent that this is a primary key

7:12

within the actual database so whether

7:14

you're using an ID a uuid you would want

7:16

that to be marked as is primary within

7:18

your model to represent that that is

7:20

your primary key then down here just

7:22

like it within the documentation example

7:23

we saw we're chaining off of our column

7:25

here an additional method called date

7:26

time as we previously discussed this

7:28

will actually take the date time out of

7:29

the database and then convert it into a

7:31

luxem date time within our model so if

7:33

we were to query our role using our

7:35

model then we would actually have the

7:36

Lux and date time value available to us

7:38

so with the date time method here we're

7:40

providing an auto create true and then

7:41

for updated out we're providing

7:42

additional auto update Trio there as

7:45

well so what this will do is whenever we

7:47

actually create a record using our model

7:48

it will auto create this created at an

7:51

update to have value based off of the

7:52

current time auto update will do the

7:54

same thing but for updating a record so

7:56

if you change a record's value so if you

7:58

change the name up data that will

8:00

automatically update to the current date

8:01

and time now there's loads of different

8:03

options for these particular arguments

8:05

and everything so the best place to find

8:06

that is within the documentation if you

8:08

go underneath preferences here for

8:09

database down here in the orm section

8:11

there is a decorator section here so you

8:13

can see all of the different decorators

8:14

a lot of these listed are going to be

8:15

for relationships which we'll get into

8:17

at a later point in time but you'll also

8:18

see you have this column one here along

8:20

with the column date and date time and

8:21

this is where you can find all of the

8:22

arguments that's the column and date and

8:24

date time decorators except so you can

8:26

see right down here in the option set we

8:28

have that column name serializes is

8:30

primary serialized prepare consume meta

8:32

and that looks to be the end of it of

8:34

this list the most important one the

8:35

note I think is the column name so if we

8:37

take a look at our actual database

8:38

you'll notice that the created that and

8:40

updated ad are snake case meaning that

8:42

they have underscores separating the two

8:44

different words that they would be if

8:46

they were in English if we take a look

8:47

at the model that was generated for us

8:49

they're in camel case so we have created

8:51

out with a capital A and then we have

8:53

updated that with capital A that's the

8:54

default naming convention with Adonis so

8:56

it expects a snake case in the database

8:58

and then camel case within your models

9:00

and this is just a developer experience

9:02

thing so that you don't have to use

9:04

snake case everywhere within your code

9:05

base you can use camel case which is a

9:07

more normalized developer naming

9:08

structure there but say you didn't want

9:10

to use that within your model say for

9:12

whatever reason you wanted to use snake

9:14

case or something else for a particular

9:15

column you can provide that in as the

9:18

column name and we could provide that in

9:19

as created at and then we can provide

9:22

whatever we wanted here for the actual

9:24

model representation so we could do this

9:27

is

9:28

created at again whatever you wanted to

9:32

essentially this column name is just

9:34

going to map whatever name we provide

9:35

here to the actual database column

9:37

created underscore at this is created at

9:40

doesn't make any sense so I'm going to

9:41

set that back to created at but do know

9:43

that column name there does exist if you

9:45

have any one Ops where you need to name

9:46

something abstract as its representation

9:49

from the database all right so that's

9:50

our role model next let's go ahead and

9:52

create our user model and for this one

9:53

let's go and use the terminal so that we

9:55

show both Fashions here so let's node

9:56

Ace make model user and let's also go

9:59

ahead and create a controller for this

10:00

so we can do hyphen C all right so it

10:02

looks like for some reason it failed to

10:04

finish out the command here but we do

10:07

indeed have our users controller and our

10:09

user model created successfully so I'm

10:11

going to go ahead and just ignore that

10:13

error for what it is and let's go ahead

10:15

and dive into our user model and you can

10:16

see we have the same thing that we

10:17

started out with with our role model so

10:19

we have an ID we've set the primary we

10:21

have created that and updated that set

10:22

the auto create and then updated app for

10:24

auto update now what we need to do is

10:26

convert all of our user columns into our

10:28

column in our models and what I like to

10:30

do for this is just to go ahead and copy

10:32

all of the different columns that you

10:33

need to actually convert into your model

10:34

columns go ahead and copy those jump

10:36

into your model go to where those need

10:38

to be added paste them in as the

10:40

migration statements that they are and

10:42

then we can use multi-line commands here

10:44

to alter this in one blow so holding

10:46

down option command or option control on

10:48

Windows hit the down arrow until you

10:50

have all of the different rows that you

10:52

just pasted and selected hold down shift

10:54

option and then you can hit the arrow

10:55

key right to highlight a whole set of

10:57

words so you can highlight table let go

10:59

of option right once more to get that

11:01

single dot character go ahead and cut

11:04

that out shift option Arrow right again

11:06

to copy the actual type for the column

11:08

now I'm going to cut this out so I'm

11:09

going to do command or control X and I'm

11:11

just going to go over highlighting two

11:12

more characters delete those out

11:14

highlight the word set and now I have a

11:17

convert to camelcase command installed

11:19

on Visual Studio code so I can do

11:20

command or control shift p and type in

11:22

camel case and then I can select this

11:24

change camel case so now those are

11:26

automatically changed the camel case for

11:28

me I'm going to hit right on Arrow key

11:29

to go beyond those column names and then

11:31

what I do at this point is note which

11:32

columns are nullable so it looks like

11:34

they're all not nullable we do want to

11:36

change our role to be not nullable but

11:37

we'll go ahead and hold down command or

11:39

control shift and then hit right on the

11:40

Arrow key to highlight the remainder of

11:42

that string and then we can hit delete

11:44

on that to get rid of it command and

11:46

then hit left to jump back to the start

11:48

of all of our strings type at

11:51

column and that hit enter type public

11:54

Command right to go to the end of the

11:57

word type colon and then paste in those

11:59

types that we copied earlier and then

12:00

hit enter to put a line break in between

12:02

all of those now we can jump down to the

12:04

end here get rid of that spare line

12:05

break and then all we need to do is go

12:07

through and convert the types from

12:09

database types to typescript types and

12:11

for our case here it's just this integer

12:13

needs to change the number and there we

12:15

have it there's our user and Role Models

12:17

setup configured and ready for us to

12:19

continue onward hopefully you enjoyed

12:20

this lesson if you did please consider

12:21

hitting the like button down below and

12:23

subscribing future lessons just like

12:24

this one we're going to be continuing

12:25

that Series going into depth on our

12:28

models here so if you'd like to learn

12:29

more please stick around I'll see you

12:31

all in the next one

12:32

[Music]

Join The Discussion! (6 Comments)

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

  1. Commented 1 year ago

    I noticed this and the last tutorial are missing the transcript -is that a bug or just not yet written?

    1

    Please sign in or sign up for free to reply

    1. Commented 1 year ago

      T'was a bug. Should be all fixed up now, thank you, Raymond!

      0

      Please sign in or sign up for free to reply

      1. Commented 1 year ago

        I can confirm - but I was also a bit confused. I was wondering why these 2 lessons don't have a "written" version like the earlier ones? I've been just reading, not watching the videos.

        0

        Please sign in or sign up for free to reply

        1. Commented 1 year ago

          Sorry about that! Since I manage this site and create the lessons in my spare time, cutting out the written portion and just focusing on video production was a decision made to help reduce the amount of time it took to create each lesson.

          0

          Please sign in or sign up for free to reply

          1. Commented 1 year ago

            Understandable, and this is an incredible resource, so thank you for what you've shared here!

            1

            Please sign in or sign up for free to reply

            1. Commented 1 year ago

              Thank you, Raymond!!

              0

              Please sign in or sign up for free to reply

Playing Next Lesson In
seconds