Course Overview and Goal0:00
Welcome to Rapid Laravel Development with Filament. I'm Kevin McKee, and I am so excited to bring this course to you. If you're wondering what is the fastest, most efficient way that I can get an Idea out of my head and build it in Laravel, I think this is the course for you. Now, we're going to do that together by building an app, and we're going to be using all six of the Filament packages. We're also going to be using a lot of standard Laravel and some other things that aren't directly related to Filament at all. If you've never used Filament or you're not sure if you're interested in it,
and some other things that aren't directly related to Filament at all. If you've never used Filament or you're not sure if you're interested in it, stick along with me because I think we're going to go over a lot of really great stuff, and a lot of it will apply maybe in different ways to your app even if you don't use the Filament ecosystem. Of course, to do this, we're going to build an app together. We're going to pretend that Taylor Otwell, creator of Laravel, reached out to us and said, I've got Larakons all over the world, and I really want software to help me manage this.
App Idea and Setup0:48
I've got Larakons all over the world, and I really want software to help me manage this. We're going to build his customized CRM to find venues and speakers for all the Larakons across the world. In order to do that, we're going to do probably the most fun thing you can do in software development. We're going to open up our terminal and do laravel new, and we're going to call this Larakonf. Of course, we need to build out our app and the structure of our app. What models are we going to use?
Introducing Laravel Blueprint1:11
Of course, we need to build out our app and the structure of our app. What models are we going to use? What database migrations do we need to create? What about our factories? We need to relate the models. We could do that the normal way. We could use the artisan commands to make our models and do that, but there's a faster way that I want to show you, and that's using Laravel Blueprint. It's a package created by JMAC who runs Laravel Shift. Let's look that up online and take a look at the docs.
It's a package created by JMAC who runs Laravel Shift. Let's look that up online and take a look at the docs. What this is going to allow us to do is generate a YAML file. In the YAML file, we'll define all the things we want. We're going to run a build command, and it's going to create everything for us. Let's go ahead and get started, and let's get this installed in our app first. We're going to do this composer require. Now let's look at the available commands we have. The first thing I want to look at is this blueprint new.
Now let's look at the available commands we have. The first thing I want to look at is this blueprint new. This is going to generate that YAML file we're going to use. We go back to our terminal, and we just run php artisan blueprint new. This created a draft.yaml file. Let's look at that in our IDE. If we look in our project, we're going to see that we have this draft.yaml file. It comes here with models and controllers. We're not going to use the controllers because we're going to use the tall stack. Filament uses Livewire and Alpine in the tall stack,
We're not going to use the controllers because we're going to use the Tall stack. Filament uses Livewire and Alpine in the Tall stack, so we aren't going to use any controllers in this application. But we do need to define our models here. Let's go back to our browser, and let's take a look at how we define our models here. We can click here. You can see here's an example. We can define the model name and the different fields it has. There's also relationships we'll get to in a minute, but let's go back to our IDE, and let's talk about some of the models we'll need for this app to track our Larikon.
Defining Models and Schema2:48
but let's go back to our IDE, and let's talk about some of the models we'll need for this app to track our Larikon. First, we're obviously going to have Conferences. A Conference has a name, which is a string. Let's also give it a description. We're going to want a startDate, and this is actually going to be a dateTime because we need to know what time it starts. We'll do an endDate as well. Let's have a status so we know is it in planning or is it already scheduled? Is it ready, not ready? Do we have more work to do?
Let's have a status so we know is it in planning or is it already scheduled? Is it ready, not ready? Do we have more work to do? Let's also add a region, and we'll make this a string as well. Is it Larikon US, EU, Australia, etc.? Then, of course, we need to know where does the conference take place? What venue is it going to be at? Now, instead of adding that information here, I want to track venue as a new model. Let's say a venueId, and this will be an unsigned integer. Then let's come down here and create the Venue model. It'll be pretty simple with a name that's also a string.
Then let's come down here and create the Venue model. It'll be pretty simple with a name that's also a string. Let's track what city it's in. We want the country as well, which is a string, maybe a postal code. That's probably enough for the venue. We can come back and define more fields later. But like I said, we do have a relationship here. Now, adding just the primary key is not the only thing that we need to do or that we can do with Blueprint. We can also actually define the relationship.
or that we can do with Blueprint. We can also actually define the relationship. If we add a relationships field here, we can add that information, and then Blueprint will actually add those relationships in the models. Let's go back to the browser and take a look at that. We're going to go up here into relationships. You can see, in our case, a Conference belongs to a Venue. The syntax here is pretty simple. We already added our relationships field here, and we just need to add belongsTo. We'll say belongsTo Venue.
We already added our relationships field here, and we just need to add belongsTo. We'll say belongsTo Venue. Then the Venue, of course, has relationships, and it has many Conferences because, of course, maybe the Conference goes back to the same Venue year after year, so it could have many. The next thing we want to add to our app is the ability to track speakers. We have the Speaker model. We have name as a string. We want the email. We can also see that a Speaker will belong to many Conferences.
We want the email. We can also see that a Speaker will belong to many Conferences. As you guys know, if you've been to Larikon, a lot of times the same Speakers will speak at multiple Conferences. We're going to have a many-to-many relationship here. Speaker belongs to many Conferences, and a Conference belongs to many Speakers. Let's add a few more fields for Speaker. We'll have a bio, which that'll be a text, and then maybe a Twitter handle. If you've actually applied to speak at a Larikon before, you'll know that these are the things that are asked when you submit your talk,
If you've actually applied to speak at a Larikon before, you'll know that these are the things that are asked when you submit your talk, which brings us to talks. We have to add talks as well. Our last model we're going to use for right now is a Talk. Let's have a title instead of a description. Let's call it an abstract. We don't need a starter and endTime. A Talk does belong to a Speaker, and let's say it could belong to many Conferences. I'm not sure.
A Talk does belong to a Speaker, and let's say it could belong to many Conference classes. I'm not sure. Maybe Taylor does allow the same Talk to be at multiple Conference instances. We'll come back up here. Belongs to many. This is the Conference model. Belongs to many Speaker and Talk as well. If you're doing this with your app, I do recommend you spend a lot of time here and really get your database schema and your models working properly because this is such a key aspect of your app.
and really get your database schema and your models working properly because this is such a key aspect of your app. Of course, you can always come back and add to this and modify it and change it, but putting in a good amount of thought up front will really make this a lot more effective for you. Let's go back to the docs for Blueprint. We've got relationships figured out. Now we really just need to look back at the commands that we have. The main command we need to worry about is the Blueprint build. This is what's going to actually build everything that we want.
Generating Files with Build6:31
The main command we need to worry about is the blueprint:build. This is what's going to actually build everything that we want. Let's copy that, go back to our terminal. We're going to run php artisan blueprint:build. You can see what files were created. We got factories for each of our four models. We got six migrations, and then we got models for each of them as well. If we look, why do we have six when we only did four models? Because it created our many-to-many pivot tables that we would need when we do that many-to-many relationship.
Because it created our many-to-many pivot tables that we would need when we do that many-to-many relationship. It's actually really nice that we have that. Let's go ahead and go into our IDE and take a look at what was generated. If we go up into app/models, let's take a look at Conference. One of the things we'll notice here, first of all, it added fillable, all the fields as fillable. I don't like to do that. I'm going to go into my AppServiceProvider right now, and in boot, I'm just going to model,
I'm going to go into my AppServiceProvider right now, and in boot, I'm just going to model, get my Eloquent model on unguard. Especially when you're using Filament, you really don't need to use those fillable properties. Filament takes care of a lot of the security for you. We're going to unguard those models. We'll come back to this in just a minute on how we can get rid of that. We also have some casts, which we do need some of those. Then you can see that we have our relationships as well.
We also have some casts, which we do need some of those. Then you can see that we have our relationships as well. A Conference belongs to a Venue, belongs to many Speakers, and belongs to many Talks. We've got all of that worked out. Let's also look at our ConferenceFactory. You can see that this was built out here as well. Some of it's really nice. The one thing is it doesn't actually get the relationships completely correct. We will have to come in here and modify the relationships a little bit.
The one thing is it doesn't actually get the relationships completely correct. We will have to come in here and modify the relationships a little bit. Another thing I'm noticing is the venue, we didn't make it nullable, but we should because there's probably going to be a lot of venues that are being considered for each conference. Until they decide on the right one, this is going to be null. In the factory, let's set it to null. Then we just need to go back to our draft.yaml file. Here, where we have the venue_id, we can just add nullable.
Then we just need to go back to our draft.yaml file. Here, where we have the venueId, we can just add nullable. Now, because we changed our draft.yaml file, we have to go back to warp. We're going to run a command that's blueprint erase. This is going to get rid of everything that we just created. Then to do it again, we can just run blueprint build. Now we have all the files that we have from before, but if we now go back into the create_conferences_table, we can now see that we have an unsigned integer for venueId,
but if we now go back into the create_conferences_table, we can now see that we have an unsigned integer for venueId, but it is nullable. Now I feel pretty good about where we are, but again, if I go back to my Conference model and take a look at some of this stuff, I don't like this. When I talk about moving fast, one of the things that helps me move fast is not having a bunch of visual clutter.
Customizing Stubs and Cleanup9:00
one of the things that helps me move fast is not having a bunch of visual clutter. You can see that my IDE is real clean. I don't have a lot of stuff around here. I don't want this here. How can I fix that without going into each file, manually deleting it? Of course, we have a command to publish the stubs. This is something that Laravel allows you to do. A lot of other packages do this,
This is something that Laravel allows you to do. A lot of other packages do this, and I highly recommend using stubs if you want to really customize your workflow. Let's go ahead and publish the stubs for Blueprint. Now if we go back to our IDE and take a look, if we close everything up here and we look at the stubs directory, now we have in Blueprint a bunch of stuff. If we go to the model fillable,
now we have in Blueprint a bunch of stuff. If we go to the model fillable, let's just delete all of this. We also have the model guarded. We don't want the guarded attributes either. Then even on the casts, I do obviously want the casts, but I don't want this comment here. Let's get rid of that. We can go back to our terminal. Again, we will run the erase command.
We can go back to our terminal. Again, we will run the erase command and we'll run build one more time. Now if I go back in my IDE, I'm going to go to the Conference model, and it's much cleaner. The last thing to do to make sure this all worked is let's go ahead and create a database table for our application. Let's add a database for laraconf.
Migrating and Testing Factories10:09
for our application. Let's add a database for laraconf. Then we're going to run to our terminal and run php artisan migrate --fresh --seed. Let's go ahead and jump into Tinkerwell and see if we can generate a Conference. See if this works. It looks like it did. We did get a factory for a Conference, and because we did the blueprint,
We did get a factory for a Conference, and because we did the blueprint, erase and then build, when we set this to null, that was erased. Let's go back and fix that really quick. The ConferenceFactory, if we look at our other factories that we have here, like the TalkFactory, again, the Talk is going to belong to a Speaker. It looks like we don't have that.
Fixing Relationships in Blueprint10:47
again, the talk is going to belong to a Speaker. It looks like we don't have that. Let's go back to our draft.yaml file and take a look. The talk belongs to a Speaker. This is one of the things about Blueprint that has actually gotten me caught a lot of times. I'm glad I can show you here. Just because you have the relationship defined where it belongs to a Speaker doesn't mean that you actually have the speaker_id here.
where it belongs to a speaker doesn't mean that you actually have the speaker ID here. We have to add the speaker_id as an unsigned integer, and then Blueprint will actually do it for you. This is something that's caught me many times. Make sure that you're aware of this as you're building everything out for yourself. One more time, let's go back to our terminal and we're going to php artisan migrate:rollback and php artisan migrate. Now this should work if we go back to our IDE.
and we're going to Blueprint erase and Blueprint build. Now this should work if we go back to our IDE. Let's go back to the TalkFactory. We now have a speakerId. In this case, you probably know this about factories already, but because this is a relationship, we can just call the Speaker class and call a factory here. When you spin up a Talk, it will create a Speaker for you. Let's do that in Tinker Well real quick. If we change this from Conference to Talk,
Let's do that in Tinker well real quick. If we change this from conference to talk, and let's save this actually as a talk here, and then we can see talk speaker. When we run this, it will create the talk. I forgot to migrate, so let's migrate fresh --seed. When I run this now, I get both the talk created and a speaker as well. This was a high-level overview of Blueprint, and it's a really powerful tool that allows you to build quickly.
Blueprint Recap and Next Steps12:10
This was a high-level overview of Blueprint, and it's a really powerful tool that allows you to build quickly. There's another video on LayerCasts where JMac himself introduces the package and shows you how to use it. If you want to learn even more about Blueprint, I suggest you do that. For us, now we have the nice structure that we need to get started, and in the next video, we're going to actually build our app.
to get started, and in the next video, we're going to actually build our app.
