What to expect in the next generation of Laravel Forge. Read the blog post
Rewatch this lesson

Next video in… 10

Showing the feed

Our first model

Getting Started with Laravel

Our first model
Build your first Eloquent model to interact with the database elegantly. Learn how models represent database tables as PHP objects with powerful features.

Like we explored in the last lesson, now that you have a database, there's a number of different ways that you can interact with that database. You can use a GUI like TablePlus or DBeaver to interact with your database, even insert new things, delete things. That's a little bit more hands-on where you have a more manual approach. Within php artisan tinker, you could use maybe raw SQL, which sounds a little crazy and a little strange and maybe a little scary.

But you can also use something like the DB facade, which Laravel gives out of the box to say, "Hey, here's a little bit easier way of working within a database." But don't worry, it gets even easier. Right now, this lesson we're going to talk about models.

If we're going back to our restaurant analogy, the M in MVC—model—is our kitchen. It prepares the food, it organizes your data structure. It keeps everything nice and neat. And in a Laravel application, you can use models to interact with your database in a really, really beautiful way—an eloquent way.

Step 1: Explore the User Model

So, as you can see here (I'm going to zoom out a little bit), we already have a model created for us. That's the User model. So why don't we take a look at what this actually looks like. Open app/Models/User.php:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Foundation\Auth\User as Authenticatable;
6use Illuminate\Notifications\Notifiable;
7 
8class User extends Authenticatable
9{
10 use Notifiable;
11 
12 protected $fillable = [
13 'name',
14 'email',
15 'password',
16 ];
17 
18 protected $hidden = [
19 'password',
20 'remember_token',
21 ];
22 
23 // ... more code
24}

There's a few things I want to point out. First, there's things like it can use specific things within Laravel, like HasFactory or Notifiable. We won't dive into either of those this course, but it's helpful to know that there are things that can interact with a model as a whole.

Next we have this $fillable array. This is just to show Laravel that people can, within your application, enter a name, an email, and a password into this table in your database. So this fillable array is the one that we're going to focus on as we create a new model for our chirps.

There are other additional arrays like $hidden or $casts, and what this does is allow you to interact with your model in even more depth. We won't touch those just yet. Models are PHP classes that represent your database tables.

Step 2: Create the Chirp Model

So let's go ahead and create our own model. Opening up our terminal again:

1php artisan make:model Chirp

And then we're going to pass it a singular capitalized name for our model. In this case: Chirp. Again, if we want to just leave that off, it gives us a little indicator of what that should be named (in this case "Flight"). But I'm not using flights, I'm using chirps.

Now before I run this make:model command for our Chirp, I did want to make a note that Laravel has these time-saving flags for models. If we were to create a model but add a dash parameter of -mrc, this would do everything that we've already done within this course:

1php artisan make:model Chirp -mrc
  • It would create the Chirp model, of course

  • m creates a migration (like we did in lesson 6)

  • rc creates a resource controller (like we did in lesson 5)

But since we already have those, we're just going to make the model.

Open app/Models/Chirp.php:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6 
7class Chirp extends Model
8{
9 //
10}

Pretty minimal! But this simple class already knows it's connected to the chirps table (Eloquent automatically converts the class name to plural, lowercase).

Heading into that Chirp model, just like I said, we want to first focus on that fillable array.

Step 3: Define Fillable Properties

Remember that $fillable array in the User model? Let's add one for Chirp:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6 
7class Chirp extends Model
8{
9 protected $fillable = [
10 'message',
11 ];
12}

So in this protected fillable array, we're just going to have our message, and this is because this is the only field in our model that we need to enter into the database. This protects against mass assignment vulnerabilities.

Step 4: Define Relationships

Next, Laravel Eloquent allows us to attach these relationships between different models. That's going to be great for us because we have users that are associated to chirps and chirps that are associated to a single user. So we can do just that.

Here's where Eloquent shines. Let's define the relationship between users and chirps:

In app/Models/Chirp.php, add:

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7 
8class Chirp extends Model
9{
10 protected $fillable = [
11 'message',
12 ];
13 
14 public function user(): BelongsTo
15 {
16 return $this->belongsTo(User::class);
17 }
18}

Now in app/Models/User.php, add this method after the existing code:

1use Illuminate\Database\Eloquent\Relations\HasMany;
2 
3public function chirps(): HasMany
4{
5 return $this->hasMany(Chirp::class);
6}

We can create a public function of user and here's where we can type hint this to say "this belongs to." We're pulling that in—this use Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsTo type. We're going to return this, which is this model belongs to, and then we can pass in the User class. So in this case, the User model.

This is letting Laravel know throughout this application, anytime we call the user on our chirps, we'll be able to grab the user's information that's associated to that single instance of a chirp or multiple chirps.

Now we want to do the inverse for what we already have within our Laravel application for our user. If I want to grab a single user's chirps, then this would be helpful.

These relationships let you do magical things like $user->chirps to get all of a user's chirps, or $chirp->user to get the chirp's author!

Step 5: Eloquent in Action

Let's test our model in Tinker:

1php artisan tinker
1// Create a new user
2$user = \App\Models\User::create([
3 'name' => 'Eloquent Expert',
4 'email' => '[email protected]',
5 'password' => bcrypt('password')
6]);
7 
8// Create a chirp for this user
9$chirp = $user->chirps()->create([
10 'message' => 'Eloquent makes database work a breeze!'
11]);
12 
13// Access the relationship
14echo $chirp->user->name; // "Eloquent Expert"
15 
16// Get all chirps
17\App\Models\Chirp::all();
18 
19// Get recent chirps
20\App\Models\Chirp::latest()->get();

Type exit to leave Tinker.

So what do these relationships actually look like in code? I kind of talked through it with you, but why don't we actually write it out? If I want to grab a chirp's user, I could do $chirp->user and this would give me something like "Hey, this is Josh. Who is the user?"

Again, this is just handy to know how all this fits together. And while this is just muscle memory to be able to learn how Tinker works and how our model works, you could do this with something like AI or even within a graphical interface to create these new users or maybe even chirps associated with the user. But this lets us know how our model's relationships also work as well.

Step 6: Update Your Controller

Now, let's go ahead and update our controller with our real data now, because if we remember in our ChirpController, we were just passing in fake chirp data. Well instead, instead of this chirps array, why don't we actually grab the chirps from the model?

Update app/Http/Controllers/ChirpController.php:

1<?php
2 
3namespace App\Http\Controllers;
4 
5use App\Models\Chirp;
6use Illuminate\Http\Request;
7 
8class ChirpController extends Controller
9{
10 public function index()
11 {
12 $chirps = Chirp::with('user')
13 ->latest()
14 ->take(50) // Limit to 50 most recent chirps
15 ->get();
16 
17 return view('home', ['chirps' => $chirps]);
18 }
19}

What's happening:

  • Chirp::with('user') - This is so that we can eager load that user relationship and it prevents N+1 queries—in that case, having to query the database multiple times for things that we already have

  • latest() - We want to grab those chirps via the latest, ordering by created_at, newest first

  • take(50) - Let's say we want to take 50 of them. Maybe this is so that we don't have all of the chirps loaded on one screen. There's other ways around this, but for now, this is going to be the easiest

  • get() - And then we're going to get those chirps

And we shouldn't have to change anything else because we're still passing that chirps variable to our home view.

Step 7: Update Your View

Update home.blade.php to use real data:

1<x-layout>
2 <x-slot:title>
3 Welcome
4 </x-slot:title>
5 <div class="max-w-2xl mx-auto">
6 @forelse ($chirps as $chirp)
7 <div class="card bg-base-100 shadow mt-8">
8 <div class="card-body">
9 <div>
10 <div class="font-semibold"> {{ $chirp->user ? $chirp->user->name : 'Anonymous' }}</div>
11 <div class="mt-1">{{ $chirp->message }}</div>
12 <div class="text-sm text-gray-500 mt-2">
13 {{ $chirp->created_at->diffForHumans() }}
14 </div>
15 </div>
16 </div>
17 </div>
18 @empty
19 <p class="text-gray-500">No chirps yet. Be the first to chirp!</p>
20 @endforelse
21 </div>
22</x-layout>

So there's a few things that we need to change in order to update our view to accept this real data. First of all, it's not an array anymore, it's an actual model, and that's going to look a little bit different.

Notice:

  • I changed things to @forelse. This is a little bit easier, but mostly so I can teach you something new. @forelse says "for all the chirps as chirp," this still exists in the same way, but if it's empty, then we can show an empty state: "There's no chirps yet. Be the first to chirp!"

  • $chirp->message - Everything that we would have passed as an array in our PHP now is the chirp message. This is associated to that model.

  • $chirp->created_at->diffForHumans() - This is a cool little Laravel helper "diffForHumans," which is going to tell us how long ago did this actually happen, that specific date. Laravel automatically converts timestamps to Carbon date objects with helpful methods!

  • $chirp->user ? $chirp->user->name : 'Anonymous' - This is just showing that it's going to say the user name if that user exists. Otherwise, it'll be anonymous because again, we have the ability, at least right now, to say that no user has to create a chirp. We can create one without having an authenticated user.

Note: We're checking if a user exists before showing their name. In lesson 11, we'll add authentication so every chirp has a real user!

The Power of Eloquent

Look what we can do now without writing SQL:

1// Get all chirps
2Chirp::all();
3 
4// Get chirp by ID
5Chirp::find(1);
6 
7// Get first chirp matching criteria
8Chirp::where('message', 'like', '%Laravel%')->first();
9 
10// Count chirps
11Chirp::count();
12 
13// Get a user's chirps
14$user->chirps;
15 
16// Create a chirp
17$user->chirps()->create(['message' => 'Hello!']);
18 
19// Update a chirp
20$chirp->update(['message' => 'Updated message']);
21 
22// Delete a chirp
23$chirp->delete();

No SQL in sight, just readable PHP!

What We've Accomplished

So what does this look like in the browser? Well, you can see this was a chirp that was created by us. We did that within Tinker. We're starting to see how this is turning into a real-world application. We're having things stored in the database, at least we're being able to then read them and also take relationships from them saying, "Hey, this is anonymous. There's no user associated with it, but this one has a user, and that user has a name."

Just to confirm how those relationships work, instead of showing user name, maybe I want to show user email here. And there we go! There's the email that I entered for my user that I created.

  • Created a Chirp model that represents our database table

  • Defined relationships between Users and Chirps

  • Used Eloquent to query real data

  • Displayed actual chirps from the database

So now your app has real data! But users can't create chirps yet. Next up: building a form to post new chirps. Time to make your app interactive!

00:00
Like we explored in the last lesson.
00:02
Now that you have a database, there's a number of different ways that you
00:04
can interact with that database.
00:06
You can use A GUI like Table Plus or D Beaver to interact with your database,
00:11
even insert new things, delete things.
00:14
Uh, that's a little bit more hands-on where you have a more manual approach
00:17
within PHP Artisan Tinker to use maybe raw sequel, which sounds a little crazy and a
00:24
little strange and maybe a little scary.
00:27
But you can also use something like the DB facade, which Laravel gives out of
00:31
the box to say, Hey, here's a little bit easier way of working within a database.
00:36
But don't worry, it gets even easier.
00:39
Right now, this lesson we're gonna talk about models.
00:43
If we're going back to our restaurant analogy, the M
00:45
and MVC model is our kitchen.
00:49
It prepares the food, it organizes your data structure.
00:52
It keeps everything nice and neat,
00:54
and in alar application, you can use models to interact with your
00:58
database in a really, really beautiful way, an eloquent way.
01:03
So, as you can see here, I'm gonna zoom out a little bit.
01:05
We already have a model created for us.
01:07
That's the user model.
01:09
So why don't we take a look at what this actually looks like.
01:13
There's a few things I want to point out.
01:15
First, there's things like it can use specific things within Laravel,
01:19
like has factory or notifiable.
01:22
We won't dive into either of those, this course, but it's helpful to
01:27
know that there are things that can interact with a model as a whole.
01:30
Next we have this fillable array.
01:32
This is just to show Laravel that people can, within your application,
01:36
enter a name, an email, and a password into this table in your database.
01:41
so this fillable array is the one that we're gonna focus on as we
01:43
create a new model for our chirps.
01:46
There are other additional arrays like hidden or casts, and what this
01:49
does is allow you to, uh, interact with your model in even more depth.
01:54
We won't touch those just yet,
01:56
so let's go ahead and create our own model.
01:58
Opening up our terminal again.
01:59
PHP Artisan Make Model.
02:02
And then we're going to pass it a singular capitalized name for our model.
02:08
In this case chirp.
02:09
Again, if we want to just leave that off, it gives us a little indicator of what
02:14
that should be named in this case flight.
02:17
But I'm not using flights, I'm using chirps.
02:19
So chirp
02:20
Now before I run this make model command for our chirp, I did want to make a note
02:25
that Laravel has this time saving flags for models that if we were to create
02:29
a model but add a dash a parameter of MRC, this would do everything that
02:34
we've already done within this course.
02:36
So would create the chirp model, of course.
02:38
So it would create.
02:38
An m, a migration like we did in lesson six.
02:41
It would create a resource controller like we did in lesson five, and
02:45
that's RC for resource controller.
02:48
But since we already have those, we're just going to make the model
02:50
Heading into that chirp model.
02:52
Just like I said, we want to first focus on that fillable array.
02:56
So in this protected fillable array, we're just going to have our
02:59
message, and this is because this is the only field in our model that
03:04
we need to enter into the database,
03:06
next.
03:06
Laravel eloquent allows us to attach these relationships between different models.
03:12
That's gonna be great for us because we have, users that are
03:15
associated to chirps and chirps that are associated to a single user.
03:20
So we can do just that.
03:21
We can create a public function of user and here's where we can type
03:25
hint this to say, this belongs to.
03:28
We're pulling that in, this use Illuminate database, eloquent relations.
03:33
Type, we're going to return this, which is this model belongs to, and
03:41
then we can pass in the user class.
03:44
So in this case, the user model, and this is letting Laravel know
03:48
throughout this application, anytime we call the user on our chirps,
03:52
will be able to grab the user's information that's associated
03:55
to that single instance of a chirp or multiple chirps.
03:58
Now we wanna do the inverse for what we already have within our
04:02
Laravel application for our user.
04:04
So if we go to our user model, we want to have this user associated to chirps, and
04:09
this is more just for simplicity's sake.
04:11
If I want to grab a single user's chirps, then this would
04:15
be helpful and we're gonna do.
04:17
Just that public function chirps.
04:20
Again, this is on the user model.
04:22
We're going to type hint this with a has many relationship and
04:26
that was imported in at the top,
04:28
and then we're going to return.
04:30
This has many and we're going to pass in again that model of chirp class.
04:37
And since we're in the same model namespace, we don't have to bring
04:41
in that chirp model, as a import.
04:44
So what do these relationships actually look like in code?
04:47
I kind of talked through it with you, but why don't we actually write it out?
04:51
If I want to grab a Chirps user, I could do this, or this is a chirp and I want
04:57
to grab the user and this would give me, uh, something like, Hey, this is Josh.
05:03
Who is the user?
05:04
Again, this is just handy to know how all this fits together.
05:07
So in PHP Artisan Tinker, and again, while this is just, muscle memory
05:13
to be able to learn how Tinker works and how our model works, you could
05:17
do this with something like AI or even within a graphical interface
05:21
to create these new users or maybe even chirps associated with the user.
05:25
But this lets us know how our models relationships also work as well.
05:30
So if I wanted to create a new user, we could use the.
05:32
User namespace, the app slash models slash user namespace, and
05:38
we want to create a new user.
05:40
Now, here's where we can input the name of Josh.
05:44
We can enter the email and maybe this is [email protected], and
05:50
then we could enter the password.
05:52
Now, Laravel gives us a easy way to enter a password without
05:57
having to encrypt it ourselves.
05:59
We can do this B Crypt function.
06:02
Where I'm going to then enter my password and then we'll just say
06:05
that this is a testing password,
06:08
and then we're going to close this out.
06:10
So there we go.
06:11
We have our new user.
06:14
So now this user can have chirps associated with it.
06:16
So why don't we do that?
06:18
We already have the users.
06:19
So now I want to create a new chirp.
06:22
So let's say a new chirp is going to be from the user in
06:26
this PHP Artisan tinker session.
06:29
We want to say that they're chirps.
06:31
I want to create a new chirp for this user, and the message
06:37
is going to be, this is a new associated chirp created by Tinker.
06:44
And again, close that out.
06:47
Oops, I had that backwards up there.
06:50
So we need the bracket and then the parentheses.
06:55
There we go.
06:56
This is a new associate chirp and it's automatically
06:58
attached to the user ID of one.
07:00
The user that we just created that is then in our user variable.
07:04
So why don't we see what this actually looks like now using that relationship?
07:09
We can echo out the chirp user name.
07:14
Oh, that's Josh.
07:15
That's awesome.
07:16
It's simple as that.
07:18
We don't have to make a fancy sequel query in order to grab that
07:22
name and then be able to make sure that that's actually our name.
07:25
It just works because we created that relationship.
07:28
And of course we can use our model in different ways too.
07:31
We can say that the app models chirp.
07:34
I want to grab all of the chirps.
07:37
Well, it's as simple as this.
07:38
We're grabbing all of the chirps.
07:39
We just have one in our database.
07:41
But, uh, that's neat to know that within one line of code, I can get all of
07:46
the chirps, all of their information, the users that are associated with
07:49
them, and we can do the same thing.
07:52
And instead of all, we can say even the latest and we'll get those as well.
07:57
And this is the same thing, but it would get the ones most recent first
08:02
where if we had multiple chirps up here for all of the chirps, it would
08:06
show them in, chronological order, the order that they were created
08:11
rather than most recent first.
08:13
And all of this is going to be extremely helpful as we start
08:15
building out our chirp application.
08:17
Because you need all of these queries.
08:19
You need these eloquent model relationships as well as knowing,
08:24
okay, how do we get the latest chirps actually sent to our view?
08:29
I am going to exit out, tinker.
08:31
Now, let's go ahead and update our controller with our real data now,
08:35
because if we remember in our chirp controller, we were just passing in
08:39
fake chirp data, well instead, instead of this chirps array, why don't we
08:44
actually grab the chirps from the model?
08:46
We can say chirp.
08:47
We can bring in that model right up here.
08:50
Use app models, chirp.
08:52
And I want to say, I want to grab all the chirps with the user.
08:57
This is so that we can eager load that user relationship and it prevents n
09:01
plus one queries in that case, having to query the database multiple times
09:05
for things that we already have.
09:07
We want to grab those chirps via the latest.
09:10
Let's say we want to take 50 of them.
09:13
Maybe this is so that we don't, uh, have all of the chirps loaded on one screen.
09:18
There's other ways around this, but for now, this is going to be the easiest,
09:21
and then we're going to get those chirps and we shouldn't have to change anything
09:25
else because we're still passing that chirps variable to our chirps, uh, home.
09:30
So there's a few things that we need to change in order to update
09:33
our view to accept this real data.
09:36
First of all, it's not an array anymore, it's an actual model, and that's
09:40
going to look a little bit different.
09:42
I'm going to pace this in, then we'll walk through exactly what changed.
09:44
First I changed things to four Ls.
09:47
This is a little bit easier, but mostly so I can teach you something new.
09:50
For four Ls.
09:51
This says four Ls, all the chirps as chirp.
09:55
This still exists in the same way, but if it's empty, then
09:58
we can show an empty state.
10:00
There's no chirps yet.
10:00
Be the first two.
10:02
then every thing that we would have passed as an array in our
10:06
PHP now is the chirp message.
10:09
This is associated to that model.
10:12
Now chirp created that, and this is a cool little Laravel helper diff for humans,
10:19
which is going to tell us how long ago did this actually happen, that specific date.
10:24
And then this is just showing that it's going to say the
10:26
user name if that user exists.
10:28
Otherwise, it'll be anonymous because again, we have the ability,
10:32
at least right now, to say that no user has to create a chirp.
10:36
We can create one without having an authenticated user.
10:39
So what does this look like in the browser?
10:41
Well, it looks like this.
10:42
You can see this was a chirp that was created by us.
10:46
We did that within Tinker.
10:48
I'm gonna go in the database and create some more just so you can see.
10:51
In our chirps, we're gonna create a new one.
10:53
We don't have to use it as a user id, but I'm just gonna say this is my second chirp
10:59
and we're going to say that this is the same date and time
11:03
just for simplicity's sake.
11:04
There we go.
11:05
We have an anonymous chirp because this chirp does not
11:07
have a user associated with it.
11:10
Lemme do this a couple more times.
11:11
And there we go.
11:12
We're starting to see how this is turning into a real world application.
11:15
We're having things stored in the database, at least we're being able to
11:18
then read them and also take relationships from 'em saying, Hey, this is anonymous.
11:23
There's no user associated with it, but this one has a
11:26
user, and that user has a name.
11:28
Just to confirm how those relationships work, instead of showing user name,
11:32
maybe I want to show user email here.
11:34
And there we go.
11:36
There's the email that I entered for my user that I created.
11:39
So now your app has real data.
11:41
You have chirps that are in the database, but you now have an easier
11:44
way to work with those chirps using models and specifically using eloquent
11:48
within Laravel to query that data, but also write that data as well.
11:52
And those relationships between users and chirps is something that's going
11:55
to make this application a whole lot easier in the end and every application
11:59
that you make within Laravel.
12:01
So next up, let's clean up our application a little bit, get some UI
12:04
niceties in there, componentize some things, and then get our database and
12:08
our application ready for users to start entering their own information.