Introducing Model Factories 0:00Alright, ladies and gentlemen, welcome back to day 10. Let's get to work. So, today we're focused on the database folder. Now, you're already familiar with migrations, and that's great. But now, the next stop on your learning is factories. So, have a look at this one that comes out of the box, UserFactory. Okay, so I see a definition method, and it looks like it has various database table attributes that consist of fake data. So, notice we have name, corresponds to any kind of fake name. And then email corresponds to a unique fake email address. A timestamp that can just be set to now. And then it looks like we also have additional methods to configure that generated user in some fashion. So, if we want a user that's in an unverified state, it looks like we can call this state method where we tweak the attributes in some shape or form. Okay, so what do we use a factory for? Well, the answer is many things. We can use a factory for any situation where we quickly need to scaffold or generate, in this case, a user. So, imagine you're writing a test, and that test says, well, given I have 10 users, when I da-da-da, then I should ba-ba-ba, right?We can use a factory for any situation where we quickly need to scaffold or generate, in this case, a user. So, imagine you're writing a test, and that test says, well, given I have 10 users, when I da-da-da, then I should ba-ba-ba, right? Well, that first step, given we have 10 users, we could use a factory to quickly generate those. Another example would be for simply whipping up your local environment. So, for example, in our case, we have job listings, right? And if I switch to TablePlus, right now we only have one. But yeah, when we're working in our local environment, it might be useful to have potentially 50 different job listings. And I certainly don't want to manually create 49 more records. So, again, a factory is a good use case for that. Okay, so we have a user factory here. How do we use it? Well, you can do it anywhere you want, anywhere you can write layer of L code. Once again, though, I'm going to reach for phpArtisanTinker. Using Factories in Tinker 2:01Well, you can do it anywhere you want, anywhere you can write layer of L code. Once again, though, I'm going to reach for phpArtisanTinker. Now, if I want a fake user, then I need to reference my user class. And actually, on that note, let's switch back real quick. So, let's go into AppModelsUser. And yeah, remember when we generated a EloquentModel using phpArtisanMakeModel, we saw that there was a useHasFactory trait. And I said, I think, let's put a pin in that just for a moment. Well, now we're taking the pin out. HasFactory adds a number of methods to the user class for generating factories. And one of those methods is, wait for it, drumroll, dot dot dot, factory.HasFactory adds a number of methods to the user class for generating factories. And one of those methods is, wait for it, drumroll, dot dot dot, factory. Okay, so let's play around. User. Factory. Create. Create a new factory for the user class. This is our API. So, I'm going to give it a run. Oh, but it fails. Oh, yeah, I remember this. Okay, this is good. This is a good learning opportunity. So, we tried to generate a new user factory, but it noticed that there's no column named name, even though the factory includes one. So, let's have a look real quick. If I switch back to user factory, yeah, this is what comes out of the box. But you'll remember a number of episodes ago, just as an exercise, we changed name to firstName and lastName. So, if I switch back and view the structure for a user, yeah, we tweaked this any number of episodes ago. Fixing Factory Attributes 3:19But you'll remember a number of episodes ago, just as an exercise, we changed name to firstName and lastName. So, if I switch back and view the structure for a user, yeah, we tweaked this any number of episodes ago. So, of course, it's failing. That's expected behavior. Okay, so we could either bring this back to a simple name column, or why don't we update this? So, instead of name, I will have firstName. And now you see this fake function here? This makes use of an API called faker, and I'll switch back here. And faker includes a variety of methods for just about any form of fake data you can imagine. And what's cool about APIs like this is you can just guess what it is. So, for example, if I want a fake name, there's probably a method called firstName, and there it is. I didn't even know that was one, but there is, right? That's the cool thing about APIs like this.So, for example, if I want a fake name, there's probably a method called firstName, and there it is. I didn't even know that was one, but there is, right? That's the cool thing about APIs like this. So, with that in mind, is there a lastName method? Yes, there is. So, I can update this as well. Okay, so we're going to give it one more try, but take a look at this. If I press the up arrow key and I run it again, it still fails. And this is an important thing to remember. When you run PhpArtisan Tinker, all of that code is loaded into memory. So, when we make changes, well, we have to exit out and then restart. So, I can press Ctrl-C to exit out, and then I will bring it back up. Alright, and now, once again, I can press up to cycle to my last command, run it, and this time it works. Okay, so notice it creates a new record within the users table, and it returns to us a new instance of that user.Alright, and now, once again, I can press up to cycle to my last command, run it, and this time it works. Okay, so notice it creates a new record within the users table, and it returns to us a new instance of that user. So, if I come back and switch to users, let's go to data, sure enough, we have a new record of fake data. Okay, but what about situations where I want many records? Well, we can do this. User, factory, and as the first argument to this factory function, we can provide a number. So, let's create, just to illustrate this, let's create a hundred fake users. Alright, that's done, it's very quick, give it a refresh, and yeah, now you can start to see the power of this. So, when you are working in your local environment, and you're playing around with some things, and you want a bunch of different job listings, well, you could use a factory to quickly scaffold them. So, let's do that now. If I switch back, yeah, at the moment we only have a single user factory. Creating a Job Factory 5:37well, you could use a factory to quickly scaffold them. So, let's do that now. If I switch back, yeah, at the moment we only have a single user factory. And of course, I could duplicate this and rename it to job listing factory, but yeah, situations like this always reach for a generator. So, control C, php artisan make factory, and yeah, don't forget, if you're confused about what argument to pass, you can proceed it with help. And I can see, alright, let's include the name of the factory, and then optionally, I can include the name of the corresponding eloquent model. Alright, php artisan make factory job factory. Alright, let's give that a run, and now we have a factory for a job. Alright, so what about the attributes here? Well, it looks like we have a title and a salary. Alright, so let's do a title, and this is a job title. So, I believe the Faker library has a method called job title, and it does. Great. Next, salary. What could we do here? We could do a fake number of sorts, or remember, it doesn't have to be random.Alright, so let's do a title, and this is a job title. So, I believe the Faker library has a method called job title, and it does. Great. Next, salary. What could we do here? We could do a fake number of sorts, or remember, it doesn't have to be random. So, in situations where it just doesn't matter whatsoever, then feel free to hard code a value. Like, if this is fine and will suit your needs, then you can do that. But if you want a variety of salaries for filtering or something like that, then you would want to make it dynamic. So, it just depends on what your needs are. Alright, and I think that should do it. So, let's give it another shot. php artisan tinker app models job factory create. So, again, notice how all we had to do is create the corresponding factory, and Laravel is smart enough to figure out what that mapping will likely be. Give it a run. Ooh, we get a call to undefined method job factory.So, again, notice how all we had to do is create the corresponding factory, and Laravel is smart enough to figure out what that mapping will likely be. Give it a run. Ooh, we get a call to undefined method job factory. Okay, let's scroll up, and I think I know why. Yeah. So, remember this particular class we created manually. Because a number of episodes ago, we already had a plain old job class to work with. But I want you to notice the difference here. If I switch to user, it uses this has factory trait. And yeah, we saw this a couple episodes ago. If we make any old model, make model post, that the generator will include this trait here. But again, because we manually created the job class, we haven't done that yet.If we make any old model, make model post, that the generator will include this trait here. But again, because we manually created the job class, we haven't done that yet. Okay, so let's delete this and manually add it on. We're going to use has factory, and notice that long path there. So, ideally, make sure you're using some kind of IDE or editor that has auto-completion. Use has factory. Yeah, you have to pull in this trait, because the trait is what affords us that factory method call. Alright, sorry about that. Let's do it one more time. Patriotisan, tinker, up, create a factory for a job, and there we go. This time we have a data processing equipment repairer.Patriotisan, tinker, up, create a factory for a job, and there we go. This time we have a data processing equipment repairer. That sounds like an exciting job, and there we go. Alright, once again, let's do a bunch. Let's do 300 random fake jobs, and again, notice how quick that is. Give it a refresh, and there you go. We got musician, physicist, warehouse, geological data technician. It's pretty cool, actually, when you think of it. Now, what about if I switch back to user? You'll remember, excuse me, let's go into user factory. Defining Factory States 8:59Now, what about if I switch back to user? You'll remember, excuse me, let's go into user factory. Okay, so you'll remember there's an additional method called unverified. And it looks like if we want a user in an unverified state, that would mean emailVerifiedAt is set to null. But notice by default up here, it's just set to null. So if we switch back, all of these users, where is it, will have the emailVerifiedAt timestamp set. Okay, so how do we activate this particular state? And that would be the term, by the way, that we use, state.Okay, so how do we activate this particular state? And that would be the term, by the way, that we use, state. Well, like this, app, models, user, factory, and then we call the state method, which is unverified, create. And that's it. So notice emailVerifiedAt is set to null. So yeah, you're not going to reach for this all the time, but trust me, once you start building more substantial projects, you'll run into situations like this where, yeah, you need to create a model or a record that's in a very particular state,you'll run into situations like this where, yeah, you need to create a model or a record that's in a very particular state, usually for the purposes of performing a test. So I'll let you take a look at this. Notice you create a method, give it any name you want, and then within that method, you call a state method on the object where you pass it a closure, a function that returns an array. Okay, so you can create these yourself as well. For example, often, we'll just do this as a quick exercise, often for simple projects, your user table might have an admin status.For example, often, we'll just do this as a quick exercise, often for simple projects, your user table might have an admin status. And let's say by default, it's set to false. You're not an admin. Yeah, maybe in certain situations, you want to say, well, given I have a user who is an administrator, when I bada bing bada boom, then I should zip zap zap, right? So yeah, that would be a good use case for a state. So I could just copy what I have here and say, okay, well, this one, this state will be called admin, and this will set the admin status to true.okay, well, this one, this state will be called admin, and this will set the admin status to true. All right, and that's it. Now you have a new piece of state. So you would say user, factory, admin, create. And now that will use all of this data, but then it's effectively going to grab these attributes and merge them and override the defaults. And that would be one way to deal with this. Lovely. Now, keep in mind, in the next episode, we're going to have a full lesson around eloquent relationships, Adding Employer Relationship 11:24Now, keep in mind, in the next episode, we're going to have a full lesson around eloquent relationships, but I kind of want to scratch the surface just a little bit to finish up this video, and you'll see why in just a minute. Now, it makes sense that any given job on our site would correspond or have a relationship to a given employer. So you can imagine if we're really popular and Microsoft signs up, then Microsoft could have a hundred different job listings, and we want that relationship to exist. Okay, so let's do this.and we want that relationship to exist. Okay, so let's do this. I'm going to go into my migrations folder to our job listings table. And now I'm going to say, well, a job listing belongs to an employer. So we'd probably want some kind of foreign ID called, I don't know, employer ID. That would make sense. So for every single job listing, there's an employer ID column that points to the corresponding employer. But right now, I don't have an employers table. So that's the next step. Let's do that real quick.But right now, I don't have an employers table. So that's the next step. Let's do that real quick. phpArtisan make. Now, we could do migration, but like we learned at the end of the last episode, we could also start with the model, which would be employer. And then I could say, also generate a migration as part of that. So let's give that a run. And now we have two new files, our employer eloquent model and the create employers table migration. Cool. So let's have a look at that right here. So an employer will have a name.Cool. So let's have a look at that right here. So an employer will have a name. And yeah, it may be, at least for a demo, maybe that's enough to get us up and running. Cool. So if we switch back to our job listings table, now, check this out. I could say, well, I could say unsigned big integer employer ID. So why are we doing unsigned big integer? Well, that's because whenever you call this ID method within a migration, that's actually creating a big integer column.Well, that's because whenever you call this ID method within a migration, that's actually creating a big integer column. Let's see if we can find it. Yeah. So it's creating a big integer that automatically increments. So when you generate your foreign keys, you want to make sure that the type of the foreign key is identical. So that's why I'm also using an unsigned big integer. However, another option is to use this table foreign ID for, and notice right here, the argument it expects is an eloquent model. So I could say, well, follow a convention and create the necessary foreign IDand notice right here, the argument it expects is an eloquent model. So I could say, well, follow a convention and create the necessary foreign ID for an employer. And that would be another way to do it. All right. So let's give this a shot. Now, because we've made some changes and we're so early in the project, I will often run migrate fresh. Just drop everything and run it from scratch. All right. So now we've built up all of our tables from the beginning. Okay. So if we come back, give it a refresh,All right. So now we've built up all of our tables from the beginning. Okay. So if we come back, give it a refresh, of course, we've lost all of our seed data, and that's fine. But if we have a look at job listings, we now have an employer ID, a title, and a salary. And the employer ID refers to this new employers table. All right. So now if we go back to our job factory, this is no longer enough. And in fact, if we try it out, where are we? There we go. Let's try to create 300 jobs.And in fact, if we try it out, where are we? There we go. Let's try to create 300 jobs. It doesn't work because, of course, employer ID was not provided. So we need to update our factory. So employer ID. But yeah, what do we set this to? Do we hard code it? Well, if that's fine for your needs, then great, have at it. It'll be the quickest option. But yeah, usually it would be helpful to say, well, whenever you generate a job, as part of that, I also want you to generate any corresponding relationships,well, whenever you generate a job, as part of that, I also want you to generate any corresponding relationships, like an employer. So we can do that by saying employer factory, just like this. So now when Laravel comes to this, it'll know, okay, we also need an employer factory. So I will generate that, persist it in the database, and then use that unique ID as the corresponding employer ID. Okay, but now this isn't going to work either, right? Let's give it another shot.Okay, but now this isn't going to work either, right? Let's give it another shot. Patriotism tinker, run it again, and it still fails. Employer factory not found. All right, let's see what the problem is. We come back up. We now have an employer model. It is using the trait, but there's no corresponding employer factory. Okay, so let's have a look at this. If I run PHP artisan help make model, yes, we know that we can use dash M to create the migration.If I run PHP artisan help make model, yes, we know that we can use dash M to create the migration. But check this out. We can also pass dash F to generate a factory as well. So here's what I'll do. I'm going to delete this just so we can do it together. PHP artisan make model. I'm not going to do dash M this time because we already have the migration. But I will say employer dash F, and now we get the model and the factory.But I will say employer dash F, and now we get the model and the factory. Cool. So here's our new employer factory. And like I said, all we have right now is a name. So I could do a fake. Maybe, is there a business? No. Company? Yeah, company. Let's do a fake company name. All right.Let's do a fake company name. All right. So are we on the same page? Now, when I want to generate a new job, it'll create a fake job title. It'll hard code a salary. And then for the corresponding employer, it'll reference an employer factory. So Laravel will read that. It will then generate a new employer record,So Laravel will read that. It will then generate a new employer record, and that will have a unique ID, right? And that ID will be substituted as the employer ID here. All right, let's give it a shot. PHP, Artisan, Tinker. Press up. And this time I'm going to generate, how about, 10 jobs. All right, and it works. All right, let's have a look in our database.All right, and it works. All right, let's have a look in our database. So I exited out, and I'm going to reopen it. Again, when you're using SQLite, sometimes you should do that when you drop the database entirely and build it up from scratch. If you ever have a situation where your table is not reflecting the change you made, it's probably related to that. All right, so here are the job listings. We have Forest Firefighter, Landscape Artist Manager, Pipefitter.All right, so here are the job listings. We have Forest Firefighter, Landscape Artist Manager, Pipefitter. And each of those belongs to a corresponding employer. So let's see. The Forest Firefighter belongs to the employer with an ID of 2, and it looks like that one is whatever, whatever this is. These all look like confusing law firm names, but that's entirely fine. And again, I want you to notice how each of these job listings belongs to its own employer.And again, I want you to notice how each of these job listings belongs to its own employer. Now, there will be situations where you want multiple job listings to belong to the same employer. And for that, you can use a method called recycle. We're not going to get into that right now, but if you want some extra credit, you could have a look at that. But yeah, otherwise, I think that's going to do it for this episode. All right, so model factories. You've learned that they are excellent for scaffolding dataAll right, so model factories. You've learned that they are excellent for scaffolding data for your local environment, and also for the purposes of preparing a test. Now, we wrapped up by learning just a little bit about database relationships. We set it up so that a job listing belongs to a corresponding employer, and we got that to work on the database end. But what about the eloquent end? So if I do have a job object,But what about the eloquent end? So if I do have a job object, how do I then fetch the name of the employer who created that listing? Well, that's going to be the subject of Day 11. I'll see you then. Bye.