Defining One to One Relationships Within Lucid Models
In this lesson, we'll learn how to define one-to-one relationships within our Lucid Models. We'll learn about the belongs to and has one decorators, their options, and types that make this possible.
- Author
- Tom Gobich
- Published
- Mar 18
- Duration
- 5m 49s
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
Defining One to One Relationships Within Lucid Models
-
(upbeat music)
-
So whenever it comes to relationships,
-
we have half of the picture taken care of.
-
We have our IDs in place on our tables
-
that inform that one table relates via that ID
-
to another table.
-
For example, this user ID informs us that one row
-
inside of our profiles table relates to one particular user
-
who has whatever ID is inside of this column for that row.
-
So if we have a profile row with a user ID of one,
-
that profile row relates to the user with the ID of one.
-
If the user ID is two,
-
that profile relates to the user with an ID of two,
-
so on and so forth.
-
And that's the database side of the relationship.
-
We also have foreign keys in place to enforce data integrity
-
so that we cannot relate to a user
-
that doesn't actually exist inside of the users table
-
from our profile.
-
But how does this relationship come into play
-
whenever we start talking about the Lucid ORM?
-
It would be nice if we had the ability to work
-
with our user record directly
-
from our profile model instance and vice versa,
-
be able to work with our profile
-
for whatever user model instance we are working with.
-
Well, good news, that's actually how the Lucid ORM works
-
whenever it comes to relationships.
-
All that we need to do is inform it
-
what we want that relationship to be named
-
and the applicable properties
-
that the relationship should use
-
to map that relationship together.
-
I like to put all of my Lucid relationship definitions
-
down at the bottom of the model
-
underneath our column properties.
-
And this will look relatively similar
-
to how we're declaring our columns,
-
except it will use its own special decorators.
-
So here we have a profile with the user ID
-
that belongs to a user record.
-
So with that verbiage in mind,
-
we can define this relationship using @belongsTo,
-
there's our decorator right there,
-
and that's going to import from AdonisJS Lucid ORM.
-
And then inside of this belongsTo decorator,
-
we're going to want to provide it
-
an instance of our user model.
-
So we'll provide this as a callback function
-
and then provide it a direct instance
-
to our user model just like so.
-
I tab to auto import that from our user model itself.
-
And then we'll want to declare the property
-
that we want this relationship to be housed on.
-
For this, it would make most sense
-
to call this property user.
-
And the type for this user is going to be belongsTo,
-
and this will be provided the type of our user model.
-
And we're getting a red squiggly on our belongsTo,
-
but that's because it wants it to be imported
-
with import type rather than a namespace import.
-
So we'll scroll up and decorate this with type just like so,
-
and everything should be A-okay.
-
And you'll also notice that that imported
-
from AdonisJS Lucid types relations
-
instead of AdonisLucid ORM.
-
And that's it.
-
That's how we define our relationship
-
from our profile to our user.
-
Now, there are some defaults being applied here
-
to make this work automatically for us.
-
If we need to change those defaults at all,
-
we can provide a second argument
-
into the belongsTo decorator.
-
And you'll see that this is an option set
-
of the type relation options.
-
With belongsTo, the one that's going to apply
-
is going to be the foreign key.
-
The foreign key with belongsTo is the relationship key
-
that is on the model we're presently working with.
-
So that's going to be our user ID.
-
So we can specify that in here just like so.
-
However, our relationship is directly working
-
with a model called user,
-
and this model's primary key is ID.
-
And that's how AdonisJS is going to map the default
-
for this foreign key altogether.
-
So in turn, we are actually making use
-
of the default already,
-
so we can keep things nice and clean
-
and remove that just like so.
-
So that will allow us to load in our user relationship
-
whenever we're working with our profile model.
-
Let's take care of the inverse side
-
so that we can work with our profile model
-
from our user model as well.
-
So let's jump over to our user model.
-
We'll scroll down to the end
-
of our model column declarations.
-
And our user profile relationship is a one-to-one type.
-
So our profile belongs to one user
-
and our user has one profile.
-
So anytime that the property of the relationship
-
is on the model itself,
-
that's where we'll want to use belongsTo.
-
On the inverse side, we just need to describe
-
how many is expected to exist for that relationship.
-
In this case, we expect it to have one.
-
So we can decorate it with a decorator,
-
noting that accordingly.
-
And in this particular case,
-
that decorator is called as one.
-
So we'll import that.
-
And this works very similar to belongsTo.
-
We provide it in a callback function
-
that returns the related model.
-
In this case, that's going to be our profile model.
-
We'll declare a property
-
that we want this relationship to be housed on.
-
And in this case, it would make most sense
-
to call this our profile.
-
And we'll define it the type has one.
-
That is a type of our profile model.
-
Looks like the auto import for these relationships
-
does not like to import with type.
-
So we'll go ahead and populate that on there as well.
-
And now we'll be able to populate a profile
-
directly for any user that we're working with
-
from our user model.
-
Just like with belongsTo,
-
we could provide a second argument
-
to this has one decorator,
-
which are option sets that allow us to define
-
what this relationship should use to relate to one another.
-
All of the other relationship decorators and types
-
are going to be the inverse of belongsTo.
-
Where belongsTo, we were making use of the foreign key
-
to relate to the property that is on this particular model.
-
So right here, our user ID is there.
-
On all of the other relationship types,
-
the foreign key is going to relate to the profile
-
that is on the relationship model.
-
So in this case, our foreign key would be our user ID
-
that is existent on our profile model.
-
So whenever you're working with a one-to-one relationship,
-
the has one would use foreign key
-
to specify the column that it would work with
-
on the related model.
-
And belongsTo would specify the foreign key
-
for the relationship column that it would work with
-
on the current model that we are on.
-
Again, though, with how we have everything set up,
-
we can make use of just the defaults
-
since our model name is user
-
and the primary key for that model is ID,
-
and it will concatenate them together as such
-
to comprise the default value for this relationship.
-
So we're good there.
-
And the same thing is true
-
with our has one decorator as well.
-
The model that we're relating to is our user model
-
and the primary key for that model is ID.
-
So this too will use the default as well.
-
So we can get rid of that altogether there.
-
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!