The Basics of CRUD
In this lesson, we'll walk through the basics of creating, reading, updating, and deleting (CRUD) data from our database using our Lucid Models.
- Author
- Tom Gobich
- Published
- Mar 02, 24
- Duration
- 11m 56s
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
Transcript
The Basics of CRUD
-
[MUSIC]
-
So now with our models defined, we're ready to go ahead and
-
start using them.
-
However, we actually already have.
-
So if you recall back, we created our movie model,
-
defined the properties that we wanted on it, and
-
then started using it by mocking the all and
-
find method within that model.
-
Well, we have since removed those methods within our model,
-
so they no longer are defined directly inside of the model.
-
But if we jump up to our movie's controller,
-
we're still making use of them.
-
And you'll notice that there's no error indicated here by
-
red squiggly either, meaning that they are perfectly valid.
-
That base model that we're extending all of our models off
-
of attaches Lucid onto the model itself.
-
And Lucid's going to provide a number of static methods
-
available to us that we can use out of the box
-
to perform CRUD-based operations against that model.
-
CRUD meaning create, read, update, and delete.
-
Now remember, a model is representative of a single table
-
inside of our database.
-
So for example, whenever we import our movie model here,
-
we're working specifically with our movie's table inside of
-
our database.
-
So by calling movie.all,
-
we're querying all movies inside of our database.
-
By doing movie.find, we're finding a particular movie
-
by that movie's unique identifier.
-
Up till now, we've been using that movie's file name
-
inside of our application to represent its unique
-
identifier, which has served the purpose of the movie's
-
slug.
-
However, that responsibility has since been transferred
-
over to the database where we now have an ID that uniquely
-
identifies the movie itself.
-
We also have a slug, but this find method specifically
-
is going to be expecting our ID because the find method
-
is going to use the primary key to look up the movie
-
based off of the value that we provide in as the argument
-
to this method.
-
And if we jump over to our movie model,
-
our primary key is indeed our ID column.
-
So all that to say we are indeed already making use of
-
Lucid to query some information from our database.
-
The only thing is, is we'll need to switch our find
-
to either params.id to represent the movie's specific ID,
-
or we can keep it as slug and switch this find method
-
to now we have a find by available to us as well.
-
The only difference between find and find by is that
-
with find by, we can specify the specific column
-
as the first argument that we want to look the movie up by
-
with the value from the second argument.
-
So for example, we could provide slug in here to now find
-
our movie by the slug that we're providing in.
-
So if we pause here for a second, open up our terminal
-
and let's go ahead and boot up our server.
-
So npm run dev.
-
Okay, let's go ahead and jump into our browser now
-
and give our application a refresh.
-
It looks like it already did it,
-
we'll do one more for sanity sake.
-
And everything's working okay, we're not getting any errors,
-
but we're also not getting any movies listed out here either
-
and that's because we don't have any data
-
inside of our database at this point in time.
-
We do with the Adonis schema
-
and Adonis schema version table that Adonis has used
-
whenever we migrated our tables,
-
but for the actual usability of our application,
-
we don't have any data to find.
-
Additionally, if we were to try to jump into one
-
of our movies inside of our navigation,
-
we're gonna get cannot read properties of null reading title
-
because the find by method wasn't able to find a movie
-
with my awesome movie as the slug inside of our database,
-
meaning that our movie itself is going to be null.
-
Okay, let's go back a step there.
-
If we wanted our my awesome movie route to fail
-
immediately whenever it cannot find the record
-
inside of the database, instead of returning back null
-
and having it fail somewhere else down the line
-
whenever we actually try to use a property
-
off of the object that we're expecting to be populated,
-
we can instead, let's hide our browser back away.
-
Instead of using find by, there is an or variant as well.
-
So or fail.
-
So now we'll attempt to find a record
-
inside of our movie database via the slug column
-
with the slug that we're providing in.
-
And if it can't, it will fail immediately right here
-
with a 404 error.
-
This also exists for find.
-
So we can do find or fail as well,
-
if you just wanna look up by a primary key,
-
but we'll leave it as slug for right now.
-
So let's give that a save.
-
We can jump back into our browser
-
and let's give this page a refresh.
-
There we go.
-
So now you see that we're getting a 404 error
-
with row not found defined,
-
and our error is happening
-
right where that call was happening.
-
This difference is happening on the type
-
of the return of that method as well.
-
So now if we take a look at the type of our movie here,
-
you'll see that it's just movie.
-
But if we switch this back to just find by
-
instead of the or fail being on there,
-
and we hover over this to see the type now,
-
we'll see that it's movie or null.
-
So there's some type safety there as well.
-
Okay, so let's jump into pgAdmin real quick,
-
dive into our servers, dive into Postgres,
-
dive into our databases.
-
Let's go into our Adonis 6 database,
-
jump down to our schemas, go inside of public,
-
and go inside of our tables.
-
Let's right click on our roles table,
-
go into view or edit data,
-
and let's click on all rows.
-
Exactly as we expect, we're not gonna get back
-
any data.
-
In order for us to start populating our database
-
with information, just like we did with our migrations,
-
we're gonna have to start in a specific order
-
because in order for us to have users,
-
we're gonna need to have a role defined
-
so that we can attach a user a specific role.
-
The same with our movies, in order for us to have a movie,
-
we're gonna have to have a movie status defined
-
so that we can attach a movie status into the movie itself.
-
And we're also gonna have to have a cynist defined as well,
-
because our movies are directly dependent on a cynist ID
-
via the writer ID and director ID
-
inside of our movie table.
-
So inserting data with the start of our application
-
is going to be similar to how we defined our migrations.
-
They're gonna have a specific order
-
that we need to work with.
-
So let's start by getting some roles defined.
-
So let's hide pgAdmin back away,
-
and let's open up our terminal once more,
-
and we can stop our server.
-
So we'll go ahead and clear it out.
-
And let's open up a REPL session inside of our terminal.
-
REPL means read, evaluate, print, and loop.
-
It's going to allow us to directly work with our server
-
inside of our terminal so that we can work with our models
-
and actually create data inside of our database
-
without having to write the actual application code.
-
And it's also just gonna let us play around a little bit.
-
So let's go ahead and do node.acelist here.
-
And if we scroll up to the top section,
-
we're gonna see REPL right here,
-
and it allows us to start a new REPL session.
-
So we'll scroll back down,
-
and let's do node.acelist.repl.
-
You'll see in yellow here that we can type .ls
-
to see a list of available context methods and properties.
-
So let's go ahead and do that.
-
So .ls, oops, I had a brain fart there.
-
Let's do .ls.
-
There we go, that's better.
-
Let's hide our text editor away too.
-
Okay, so the first couple of arguments
-
are going to allow us to import modules.
-
We don't need to do that right now.
-
What we wanna do is work with models.
-
So if we scroll down a little bit to the load section here,
-
we'll start seeing some load options,
-
and right here is load models.
-
This is going to allow us to recursively load in
-
our Lucid models directly inside of our terminal
-
so that we can work directly with them here.
-
So let's go ahead and call load models, just like so.
-
Cool, we probably should have awaited that,
-
that return back a promise, but everything worked A-okay.
-
Our models are indeed loaded,
-
and we can access them by using models.
-
So if we type out models,
-
we're gonna see that we have an object.
-
First is our movie,
-
and then it's gonna go on with the type of the movie onward,
-
but we do have all of our models accessible.
-
So let's go back a little bit here,
-
and let's await models.
-
And let's do our role to access our role model.
-
And just like we're doing with our movie model
-
inside of our movie controller,
-
we can call .all here just to see if everything works.
-
So we'll go ahead and hit enter on that.
-
And you see that we get back an empty array,
-
indicating that we do indeed have no data
-
inside of the table.
-
So let's go ahead and try await models role,
-
and there's a create method on here as well
-
that will allow us to pass in an object of information
-
to define a specific row for our role table.
-
And since we're working with our Lucid model,
-
Lucid's going to automatically take care of assigning
-
and updating our created at and updated at as needed
-
whenever we're working directly with the model.
-
So all that we need to do is define a name for our role,
-
and we'll be good to go.
-
So let's hide that back away,
-
and let's go ahead and define a name.
-
For our first role,
-
let's just say they're a typical user
-
inside of our application.
-
So we'll go ahead and hit enter there.
-
And we're going to see that we get back an instance
-
of the model record for the specific row that we created.
-
And a lot of these columns that we see
-
are here for Lucid's sake,
-
so that they know the particular state
-
that the model is within,
-
whether or not any information has been mutated on it,
-
whether or not it's been persisted,
-
whether or not it's a part of a transaction,
-
things like that.
-
The information that we care about
-
is going to be within the attribute section,
-
where we can see that the name of the underlying record
-
that was created is user, just as we defined it.
-
The ID was assigned as one.
-
And the created at and updated at are date times,
-
specifically Lux and date times,
-
where the current time is 2024, February 25,
-
at about UTC 143.
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!