Transcript
-
- So to get started with querying and building out information for our application, it would be really nice if we didn't have to go
-
and create hundreds of movies, cast members, and all that fun stuff ourselves, but instead just had an automated system to be able to easily spin up
-
as many of those particular items as we wanted to. That's where Factory's coming to play. So within our terminal here, if we do node ace list, to see the list of the commands,
-
you'll see underneath the make section, make factory. A factory is essentially going to allow us to stub a model with faker information or fake data.
-
So let's go ahead and create a factory here. So let's do node ace make. We're gonna need Cineasts before we actually have movies or anything of the like. So let's start with our Cineasts.
-
So let's do a factory. And let's do hyphen hyphen help here to see the available commands. You'll see that the first argument is just going to be the model name.
-
So all that we need to do is node ace make factory. And to create one for our Cineasts, we just do Cineasts. I think I misspelled that. There we go, Cineasts. Hit enter there. And that's gonna create a factory for us
-
inside of our database, factories, cynists_factory.ts file. So let's open up our text editor here and let's take a peek at it and see what it is. So let's go to factories, Cineasts factory.
-
Cool. So you'll see that it's already importing our Cineasts model automatically for us. And it's defining a factory specifically for that. So it's returning back a callback function inside of this define for our factory,
-
providing us faker information inside of here, and then returning back an empty object. Lastly, calling build to build out the factory. All that we need to do is define the information
-
for the model itself inside this object that it's returning. If we take a quick peek at our Cineasts model, we have a first name, last name, and headshot URL that we need to populate. Everything else should be automatically taken care of
-
by either the database itself, which is our ID, or by Lucid itself, which is our create at and update at. Cool. So let's dive back into our factory. So start with first name.
-
We can reach for faker dot, and we'll have a number of different items that we can select from. So we have an airline, an animal, color, commerce, company, database, data type, date, all that fun stuff.
-
We have image that might come in handy here in a second, but if we keep scrolling down here, we'll see person. Perfect. That's exactly what we're looking for. So we can take a look at what person offers, and look at that.
-
We have first name right there. So let's go ahead and use first name. If there's a first name, we can probably assume that's too going to have a last name. So do faker person dot last. Perfect.
-
And then I think the other one was a headshot URL. Sure it was. So we can do faker. Let's see if person has a headshot URL or anything of the like in here. So let's see. Bio job title prefix.
-
Nope, it does not. Though it does have a Zodiac sign in case you have a need for that. So cool. Okay, let's try maybe image. We saw that earlier on,
-
and we see a number of deprecated things within here. So avatar right up here, or avatar GitHub, or legacy. One of those would probably do just fine, maybe even Flickr.
-
We'll go ahead and use just avatar here. That should serve our purpose well enough. So we can give that a save, and we're off to the races. Now our start seeder is specifically for start information
-
that our database needs to get up and running. Whenever it comes time to actually make use of our application, we're not going to want this faker information to actually exist inside of our database.
-
So we'll define the faker information as a separate seeder that we can use as an optional seed to get things going. So we'll jump back into our terminal here, and we'll create a new fake seeder.
-
So node ace make fake seeder, just like so. Oops, sorry. Node ace make seeder fake seeder. Okay, there we go. That one's right.
-
So now we have our fake seeder there. And again, just like we did with our start seed, all we need to do is create the information that we want to exist inside of our database inside the run method of the seeder.
-
So right in here. And we can use our factory in place of our model to create that information. So we can await, sin, and you'll see within our autocomplete list here,
-
we have our sinist_factory. Let's go ahead and click on that to import it from our factory and let's see what our options are. So if we do dot, we'll see that we have both a create
-
and create many method, just as we do with our lucid model. So we can use those to create information inside of our database using the factory. So let's click on create many there
-
because we're gonna want many sinist. And the argument for this is just gonna take in a count of the number of records that we wanna create. So for now, let's just start it with 10. Cool, so we can give this a save
-
and let's see if everything works. So let's jump into our terminal here. Let's clear this out so it's a little cleaner. And let's try to run using the same command that we ran last time.
-
So that's node, ace, db, colon, seed. By default, this is going to run all of our seeders. So if we hit run, you'll see that we get an error because it cannot create another role
-
with an ID of one or two. So that's gonna violate that unique constraint on the primary keys. So whenever we run this in the future, although our fake seeder did complete successfully,
-
we're gonna want to use that files argument to explicitly define that we just wanna run the fake seeder. But since that did complete, we should be a-okay to keep it as is for right now.
-
So let's hide that away and just keep that in mind for future reference. Dive back into pgAdmin and we can right-click on our sinists, go down to view edit data and click on all rows.
-
And voila, we have now 10 fake sinists, each with a first name, last name, and some form of a headshot URL. Awesome, so everything seems to be working a-okay there.
-
Okay, just wanna add a quick note here about the order of execution on our seeders. They're gonna use a natural sort, the exact same as our migrations do. So whatever order we see them listed in here within our file tree,
-
that's the same order that they're gonna try and run in. And we always want our start seeder to run before our fake seeder because our start seeder contains the roles and our statuses,
-
which the fake seeder relies upon to exist in order for that to run successfully. So we do apply this fix in lesson 4.16 whenever we run into this, but I wanna make a note about this here
-
so that you don't get tripped up on it if you try to rerun your migrations and seeders in between now and then. And thanks to ChristoXZ down in the comments
-
for noting that I did miss this in between now and then, and that it is a potential trip up point. So what we wanna do is right click our start seeder and just prefix this with something like 00
-
since we always want this to run first. 00 is going to naturally sort it before our fake seeder. And then we can also apply just a sort to our fake seeder
-
just to ensure that it runs next should we add any future seeders down the road. So we can do 01 there, and that mutates the natural sort and thereby the order of which
-
AdonisJS will run these whenever we run our DBC command. So our start seeder is always gonna run first. And then once that succeeds, it will move on to our fake seeder in the order that we need it to run. Cool, so let's continue onward
-
and continue defining our factory. So we'll do node ace make factory. We have explicit values that we have within our start seeder for both our roles and our movie statuses tables.
-
So we're not gonna need fakers for those because we already have real world data that we want our application to use populated within there from that start seeder, which leaves us with our users,
-
our Cineasts, which we've just created a factory for, and our movie table. Now, also remember that we have crew movies and cast movies tables inside of our database that serve as many to many pivot tables.
-
We don't need those defined as models because they'll be able to be joined together via the relationship that we'll define in the next module. So we can ignore those for now
-
and just focus on these models that we have here. So let's do a factory for our movie next. Okay, cool. So we have that one created. Dive down into there. And we have a number of different properties on our movie.
-
So I'm just gonna drag our movie model over here onto the right-hand side of our screen and hide our explorer away using Command or Control + B. Now, this model in particular has a number
-
of different relationship based IDs specifically on it. And we haven't defined anything relationship based yet, but these IDs are required.
-
So for right now, for our factory, we're just going to stub these with hard values. So for our status ID, we actually have this within the enum. So we can put a specific hard value here if we wanted to.
-
So we could import our status ID enum. Movie status is right there. And for right now, let's just put them all in writing. And then we have our writer ID. We'll just hard code those to one
-
and our director ID as two so that there's a slight difference between the two. And then we should be good to continue onward with the rest of our Faker information for the rest of the properties. We'll circle back whenever we get to relationships
-
and fill these two in with relationship based information. Cool, so let's do our title next. And we can reach for Faker. So let's see what we have. Let's see if there's a movie in here.
-
I doubt it, but you never know. We have music. I don't see movie. Okay, yeah. So I don't see anything from movies, but we could probably use music as that's fairly close. It's probably the closest thing
-
that we have available in here. So we'll go ahead and click on music and let's see what we got there. So we have genre and song name. So let's go and do song name. That'll serve our purpose well enough. And next we have our slug.
-
Now in our final application, we're going to want our slug to be a URL safe representation of our title. For right now, we don't have anything for that in place.
-
So we can use Faker to just add in some slug within here so that we have that populated. Later on, we'll automate that process inside of our model so that anytime that we save a new record
-
inside of our movie table, our model will convert the title into a URL safe representation for our slug. For now though, we will just use Faker and we can use the string option
-
and just plop a UUID in here for right now. That should serve as a URL safe version of a string that we can plop on the slug for right now. Okay.
-
And then we have our summary. For this, let's just put some lorem on it and let's just put it to a single sentence. Okay. And then we have our abstract, which is a long form string.
-
So we could put whatever we want in there. So let's do abstract. Lorem will probably be the most appropriate. So we'll do that. And for this one, we can do paragraphs and we'll just let it put whatever it wants inside of there.
-
And then we have our poster URL. So Faker, just like our headshot URL, this will be an image dot and let's just use, pick some photos for this one. Okay.
-
And that should do it. We're now down to our created at and updated at, which our model will take care of for us. So that should be our movies factory. We can close our model and open back up our Explorer with command or control B.
-
And lastly, let's create our user factory before we do anything else. So let's jump back into our terminal, node, ace, make factory, user. There we go. Jump back into our text editor,
-
jump into our user factory and let's define the properties for that. So we can drag that back over to the right-hand side as a reference, close our Explorer and scroll down just slightly here.
-
Again, we have our role ID, which uses a relationship. For right now, we'll just hard code something in here. So we can do roles to import our rolling num and we can assign a user
-
or we could leave this out altogether and just have the database's default value auto-populate this for us, but so that we don't forget about it, let's leave this in here as an explicit value. And for this one, we have full name.
-
So we can do full name as Faker, leave person was the property that we used on the other one. And there should be a full name option in here too. There we go. Then we have our avatar URL.
-
So we'll do Faker image and let's do avatar. And then we have an email. So Faker, the internet property should be what we want for that. And there's an email right there. All right, we'll scroll down a little bit.
-
Okay, looks like the last thing that we need is our password. So we'll do password Faker. I bet you internet's gonna have that. So we'll do internet.yep, sure enough, password. Cool.
-
Now we haven't discussed this at all yet, but if we take a look at our user model, scroll up to the top, it's using this auth finder right here. And that's being composed into our user model. Remember, composed just kind of joins together
-
two classes that we want to extend. And it's composing that with the base model. So everything that provides us lucid functionality. This auth finder is going to add in a hook
-
so that anytime that we save the model instance, it will check to see whether or not the password value has been changed. If the password value has been changed, it will hash it and secure it inside of our database
-
so that it's not stored in plain text automatically for us. So let's jump back into our factory. And whenever we create our user, we'll see exactly that.
-
So we'll get some plain text value provided into Faker here, and then our system will automatically hash it and secure it inside of our database. So let's jump back down to our fake seeder and let's await.
-
We'll do our movie factory here, .createMany. Let's just create three of those and then await user factory .createMany.
-
And let's create five users. So we can give that a save, jump back into our terminal. Let's clear this out. And let's run node, ace, bb, seed, hyphen, hyphen, files,
-
equals, and then we want to point it to the particular file path that we want to run, which is our fake seeder. And this will allow us to only run our fake seeder instead of our start seeder.
-
So we can do database, seeders, fake_seeder.ts, hit enter there, and there we go. It just ran our fake seeder and it completed successfully.
-
Now you'll note that we had already run this with our Sinist factory. So our Sinist factory has now run twice. So we'll have 20 Sinists inside of our database,
-
but we'll only have three movies and five users because those two have only run once. So if we dive back into pgAdmin, refresh our Sinist by hitting play button right there,
-
we should now have 20, which we do indeed. We can go over to our movies, right click on that, view edit data, all rows. We should have three of those, sure enough.
-
And remember we hard-coded the status ID, writer ID, and director ID, so those will all be the same, but we do have our dynamic movie titles, our slugs, which we set to the type of GUID,
-
which looks right, some lorem summary, and a lorem abstract. And if we continue scrolling over, we should lastly have our poster URL, sure enough. And, oh, forgot all about the release step,
-
but that is nullable, so that's a-okay. Okay, cool. So let's scroll back over and let's lastly run our users. So let's right click on that, view edit, all rows. There we go, we have five of these
-
with the full name populated. They have an avatar URL, there's their email, and there is their secure password. It was secured using script, which is the default hashing mechanism.
-
So we are unable to see the plain text value that was assigned into Faker inside of our database, making our passwords nice and secure. You never wanna store your passwords in plain text.
-
If your database ever becomes compromised, their password is also compromised. Always make sure you never store your passwords in plain text, okay. And then we have our created at and updated at there, so everything looks good.
-
I'm gonna go ahead and put the release that inside of our factory so that we don't forget about it again. Oh, let's see, that was our movie factory. Okay, so released. And we can just put that to null, since it's nullable.
-
And the status ID is being set to writing instead of released at this point in time anyway, so that matches with what we would expect. Okay, cool.
-
Now, since our fake seeder specifically creates fake information using our factories, we don't want this to actually execute within production. So we can use an environment specification
-
inside of this seeder to specify that we only want it to run in certain environments. Specifically for this use case, probably just development, but we could also include testing if we wanted to.
-
So we're gonna add a static property onto the class here called environment and set this to an array. Inside of this array is where we define the environments. So first, we're definitely gonna want this
-
to run within development so that we can create the fake data to actually use throughout development. If you wanted it to also be executable within testing, we could include testing there as well.
-
The one that we don't want to include is production. So be sure that you leave that out of any faker-based seeders so that you don't have fake data out in your production environment.
-
So these are the only environments that the seeder will run whenever we attempt to use node-ace-db-seed. In fact, for right now, I'm gonna go ahead and just leave this as development.
Stubbing Fake Data with Model Factories
We'll learn how we can quickly and easily bulk-create dummy/fake data within our database for each of our Lucid Models using Model Factories

- Created by
- @tomgobich
- Published
- Last updated
Join the Discussion 0 comments
Be the first to comment!