Querying Relationships and Eager Vs Lazy Loading
In this lesson, we'll learn how we can query our relationships using our Lucid Models. We'll then learn what the difference is between eagerly loading a relationship (load) and lazily loading a relationship (preload).
- Author
- Tom Gobich
- Published
- Mar 18
- Duration
- 5m 17s
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
Querying Relationships and Eager Vs Lazy Loading
-
(upbeat music)
-
So now that we have our user profile relationship
-
defined within our models,
-
and we have actual records created
-
making use of this relationship,
-
how do we go about querying it?
-
Well, there's a few different ways
-
we can actually go about this.
-
So let's go ahead and clear our terminal out
-
and node is ripple to jump into a ripple session.
-
We'll await load models,
-
and let's do const user equals await models user
-
find or fail the user with the ID of one.
-
We'll go ahead and hit enter for that.
-
And now we should have our user just like so.
-
And there's a few things that we can do with this user.
-
So first we could do related to reach for any relationships
-
based off of this particular user instance.
-
And here we just define the relationship name.
-
So within the model, we've called this relationship profile.
-
That's the declare property that we defined.
-
And now we can do dot query to access the query builder
-
for the profile related to this particular user record.
-
Meaning that if we just ran this
-
with just the query builder there,
-
Oh, hold on a minute.
-
I forgot to await that.
-
Let's jump back up and let's await the results.
-
There we go.
-
That looks a little bit more right.
-
So real quick, whenever we did not await,
-
we actually got a lot back.
-
So we got relationship information,
-
parent model information, client options,
-
all of that fun stuff, preloader information,
-
essentially defining the underlying query
-
that Lucid would have to build
-
to get to the underlying result for the relationship.
-
And right here, you can see the model
-
that we're intended on querying itself,
-
which is our profile class, contains key information,
-
the column definitions on that model,
-
relationship definitions, hooks, so on and so forth.
-
So if you do not await, it won't actually run the query,
-
but it will instead just return back information
-
about the model itself.
-
And in that case, we were working with a relationship,
-
so it was returning back relationship information as well.
-
But since we've awaited this one,
-
now all that we get back is the underlying relationship
-
record that we had intended on querying.
-
And you'll notice that we just get back one result here
-
because we only have one profile
-
that belongs to this individual user record.
-
If we go ahead and run OYO on this
-
so that we can actually see the properties
-
on the profile model that we're querying,
-
you'll see it has the user ID of one,
-
which matches our user's ID
-
that we're using to query the profile with.
-
So essentially this approach here is building out for us
-
await models.profile.query.where user ID is one.
-
And it's using the relationship information
-
that we've defined on both of these models
-
to grab the primary key from the user
-
that we're using to query from,
-
and bind that in to the appropriate where statement
-
for the underlying query builder
-
via the relationship that we are working with.
-
If we were to add OYO to this and run it,
-
you'll see that we get back the exact same result
-
because both the underlying queries that ran are the same.
-
Another thing that we can do is we can load the relationship
-
directly onto the user record itself.
-
So we can await user.load,
-
and then specify the relation that we wanna load.
-
In this case, that would be our profile.
-
And this approach here is called lazy loading
-
because we already have a reference to our user record.
-
And we just want to lazily load the profile relationship
-
onto this record.
-
So if we hit enter here,
-
we get back undefined because nothing was returned.
-
However, if we now do user.profile,
-
we actually have our profile model
-
directly available to work with.
-
And you'll see all of the original information
-
directly on here.
-
And it looks just like a typical model,
-
meaning that we can also do user.profile.description,
-
and voila, there's our profile description just like so.
-
Now this user profile isn't available
-
until we either lazy or eager load the relationship in.
-
For example, if we do const another user
-
equals await models.user.findOrFail,
-
and we provide an ID of two
-
so that we have a different user here.
-
Let's go ahead and run that.
-
And now if we do another user.profile,
-
we're going to get back undefined.
-
But if we await another user.loadProfile,
-
we've now lazily loaded the profile information
-
onto another user.profile.
-
So we can hit up twice and look at that.
-
There's our profile information for our user
-
with an ID of two.
-
So that approach is referred to as lazy loading,
-
but what about eagerly loading?
-
Well, that's where we start with our user
-
already having the profile information populated.
-
Okay, so I've gone ahead and jumped
-
into a fresh REPL session and reloaded our models
-
just to clear everything out here.
-
And now what we can do to eager load a relationship
-
onto our user without having to lazily load it in later on
-
is we can make use of the query builder.
-
So if we do const user equals await models user.query
-
to get access to the user query builder,
-
we'll do where ID is one to get the user with an ID of one.
-
And then we'll use a method called preload
-
to preload a relationship onto the returned user result.
-
So if we do profile here,
-
and let's just grab the first or fail record.
-
We'll hit enter there.
-
And now we should have access immediately to user profile,
-
just like so, awesome.
-
What's really nice about this approach
-
is that we can quickly eager load relationships
-
on multiple records.
-
So we can do const users equals await models user query.
-
And if we just preload our profile here
-
without specifying a where to hone this down at all,
-
and we just run this query here,
-
we now have all of our users in this variable users,
-
which in our case should be five.
-
So if we access the first index,
-
we now have our first user record
-
inside of our array dot profile.
-
We now have direct access to our first user's profile.
-
And if we switch this index from zero to one,
-
there's our second user's profile, third, fourth, and fifth.
-
And then lastly, we don't have a sixth user.
-
So that one's going to be defined, awesome.
-
And we can chain off of this direct properties as well
-
to get direct access to them.
-
So whenever we're preloading using the query builder,
-
that's referred to as eager loading.
-
And whenever we take a user record and load onto it,
-
this is referred to as lazy loading.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
The Flow of Middleware7m 49s
-
Authenticating A Newly Registered User4m 14s
-
Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!