What to expect in the next generation of Laravel Forge. Read the blog post
Rewatch this lesson
Courses
/
Getting Started with Laravel
/
Working with the database

Next video in… 10

Our first model

Working with the database

Getting Started with Laravel

Working with the database
Set up your database with migrations and learn Laravel's database tools. Create tables programmatically and explore different ways to interact with data.

Alright, we have these sample chirps that we're passing to our view layer. Again, this is our controller—the C of the MVC structure—and we're passing this to our V, our view layer. But these chirps are just hardcoded values that we're passing from this controller. They don't actually exist in the database.

So when you're creating an application, when you're putting it out onto the web, most of the time you need a database in order to save things that can then live forever—or at least until someone deletes their chirp.

Laravel's Database Magic

Good news: Laravel already set up a database for you! Remember when you chose SQLite during installation? It's been waiting patiently at database/database.sqlite. SQLite is perfect for learning—it's a real database that lives in a single file, no server required and it works with your local development environment seamlessly.

Step 1: Meet Migrations

Migrations are like version control for your database. Instead of manually creating tables, you write PHP code that describes your database structure. Laravel can then create, modify, or rollback your database changes automatically.

Let's create a migration for our chirps table:

1php artisan make:migration create_chirps_table

This creates a new file in database/migrations/ with a timestamp and name. Open it up:

1<?php
2 
3use Illuminate\Database\Migrations\Migration;
4use Illuminate\Database\Schema\Blueprint;
5use Illuminate\Support\Facades\Schema;
6 
7return new class extends Migration
8{
9 public function up(): void
10 {
11 Schema::create('chirps', function (Blueprint $table) {
12 $table->id();
13 $table->timestamps();
14 });
15 }
16 
17 public function down(): void
18 {
19 Schema::dropIfExists('chirps');
20 }
21};

Step 2: Design Your Table

Let's add the columns we need for chirps:

1public function up(): void
2{
3 Schema::create('chirps', function (Blueprint $table) {
4 $table->id();
5 $table->foreignId('user_id')->nullable()->constrained()->cascadeOnDelete();
6 $table->string('message', 255);
7 $table->timestamps();
8 });
9}

What's happening here:

  • id() - Creates an auto-incrementing ID (primary key)

  • foreignId('user_id') - Links each chirp to a user

  • nullable() - Makes the user_id optional for now (we'll fix this when we add authentication)

  • constrained() - Creates a foreign key constraint

  • cascadeOnDelete() - If a user is deleted, delete their chirps too

  • string('message', 255) - The chirp text (max 255 characters)

  • timestamps() - Adds created_at and updated_at columns automatically

Note: Making user_id nullable isn't recommended for production, but it lets us see our app working in the browser before we tackle authentication. Laravel gives us a User model out of the box, but to keep things simple, we'll build up to authentication gradually. We'll make this field required when we add user registration and login.

Step 3: Run the Migration

Time to create the table:

1php artisan migrate

You'll see output like:

INFO  Running migrations.

2024_01_15_123456_create_chirps_table ................... 28ms DONE

Your database now has a chirps table! 🎉

Step 4: Explore Your Database

Want to see what you just created? You can use any SQLite viewer, but Laravel provides a handy tool called Tinker:

1php artisan tinker

Then type:

1\DB::select('SELECT * FROM chirps');

You'll see an empty array [] because we haven't added any chirps yet. Type exit to leave Tinker.

For a visual approach, tools like TablePlus, DBeaver, or even VS Code extensions can open your database/database.sqlite file and show you the tables.

Step 5: Understanding the Users Table

Notice that user_id column? It references the users table. Good news—Laravel already created this table for you! Check out database/migrations/ and you'll see a create_users_table migration that ran when you first set up the project.

The users table has:

  • id

  • name

  • email

  • password

  • remember_token

  • timestamps

This is why we can link chirps to users—the infrastructure is already there!

Manual Data (Just to See It Work)

Before we move forward, I do want to manually create a chirp with php artisan tinker, mostly to show you that there's an easier way to do it in the next lesson—an easier way to interact with our database, even with the tools that Laravel gives us through models.

But also to show you that Tinker or any way that we're interacting with our database is a great use case for something like AI. Within Laravel Boost, there's tools that allow you to work with Tinker or allow your AI assistants to work with Tinker. You don't need to know all of this syntax for how to interact with the database through Tinker, but it's helpful to know what your AI, or even what specific commands might do.

Let's manually add a test chirp:

1php artisan tinker
1// We're entering into the chirps table for selecting the chirps table
2// and then inserting a message
3\DB::table('chirps')->insert([
4 'user_id' => null, // Because we don't have a user, we can just leave it off
5 'message' => 'My first chirp in the database!',
6 'created_at' => now(), // Laravel doesn't give these by default when using DB
7 'updated_at' => now()
8]);
9 
10// And we get this true back. So that means that this was successful,
11// this chirp was now entered into the database!
12 
13// Check it worked (all chirps)
14\DB::table('chirps')->get();

And there we go. Here's our first chirp. Congratulations! You just entered something into the database using a command line tool. Type exit to leave Tinker.

Note: This might seem tedious to interact with the database in this way. The good news is we will explore easier ways to interact (even within Tinker) in the next lesson. Laravel Boost also provides AI Assistants an easy tool to use Tinker within your Laravel application.

Migration Rollbacks

Made a mistake? Migrations can be reversed:

1php artisan migrate:rollback

This runs the down() method, dropping the chirps table. You can then modify your migration and run php artisan migrate again.

Warning: Rolling back will delete any data in those tables!

What We've Built

You now have:

  • A real database (SQLite)

  • A chirps table with proper structure

  • A foreign key relationship to users

  • Version-controlled database changes

But typing SQL queries is no fun. Next, we'll create a Model that lets us work with chirps using beautiful, expressive PHP code. No more SQL strings!

Pro Tips

  1. Migration files are timestamped - This ensures they run in the correct order

  2. Never edit old migrations - Create new ones to modify existing tables

  3. Keep migrations in version control - Your team needs them too!

  4. php artisan migrate:fresh - Drops all tables and re-runs migrations (careful in production!)

Ready to make working with the database feel like writing poetry? Let's create our Chirp model!

00:00
All right.
00:00
We have these sample chirps that we're passing to our view layer.
00:04
Again, this is our controller, the C of the MVC structure, and we're
00:08
passing this to our V, our view layer.
00:12
But these chirps are just hard coded values that we're
00:14
passing from this controller.
00:16
They don't actually exist in the database.
00:17
So when you're creating an application, when you're.
00:20
Putting it out onto the web.
00:22
Most of the time you need a database in order to save things that can
00:26
then live forever, or at least until someone deletes their chirp.
00:30
In lesson two, we talked about how we have this database SQL Light, the same
00:34
one that was generated for us when we created the initial Laravel application.
00:38
When that Laravel installer scaffolded it out, database dot SQL light is perfect
00:44
for our local development environment.
00:46
'cause it's a real database.
00:47
Everything exists.
00:48
In this single file.
00:50
So the TLDR is squa light is a great option for a database, and if you did
00:55
want to move it into production using a different database, you really don't have
00:58
to think too much about what that changes.
01:01
Laravel just handles all that for you.
01:03
But let's go ahead and get started with interacting with the database.
01:06
And to do that, we need this little thing called migrations.
01:10
In fact, we have a directory already enabled for us that
01:13
has some migrations by default.
01:16
But we're gonna go ahead and create one from scratch.
01:19
You can think of migrations as Elle's way of interacting, creating,
01:23
modifying, even rolling back.
01:26
Your database changes automatically.
01:28
So it's a, uh, file based way of saying, Hey, here's what is happening
01:32
or has happened with your database.
01:34
We are gonna open up that terminal again using our handy PHP Artisan Command.
01:38
We're gonna say make migration.
01:41
And again, most of the time I could just leave this blink and if I was to
01:45
press enter, it would give us the, uh, standard format of what a migration
01:52
might be named and how you would
01:54
input that into this field.
01:57
So I'm just going to say that this is create chirps table because
02:02
that's what we're going to do.
02:03
We're going to save chirps to our database.
02:06
So we need a chirps table.
02:08
And this is plural, just like it gave us a prompt for.
02:11
Now that went ahead and created that file for us.
02:14
So if we were to open up that database directory again, we
02:17
should have a new migration.
02:19
Yes.
02:19
This last one, and it's timestamped as well for when we created
02:23
it, create chirps migration.
02:26
Here's where we get to add the columns that we would need in our database for
02:30
our chirps you can think of this as how your database needs to be defined.
02:34
What things do you generally store with a chirp entity?
02:38
now first, most of the time a chirp would be associated with a user.
02:42
We need to know who actually proceeded to chirp.
02:46
Now Laravel gives us a handy table column for this.
02:49
We can say column, foreign id, and now here is where we can pass in the
02:54
ID of another column in our database or another table in our database.
02:59
For example, I'm gonna say this is the user I Id.
03:03
And I'm going to make this knowable.
03:05
Now, this isn't recommended in a production database, but just so that
03:08
we can continue moving forward with our application, we don't necessarily
03:13
need a user just for testing purposes.
03:16
We wanna be able to create chirps, edit them, delete them without
03:19
having to worry about authentication.
03:21
We'll get to that at a later lesson.
03:23
And then I'm going to say that this is constrained.
03:25
What this does, you can see this right here, it creates a foreign key constraint
03:29
on this column referencing the ID column of the conventionally related table.
03:34
What that means is it's grabbing the user ID and then saying it's going
03:39
to exist within the user model, the user table within our database.
03:45
And then this is something you might normally do within an application.
03:48
I'm going to have this cascade on delete.
03:51
Now, what does this mean?
03:52
It means that anytime a user is deleted, their chirps are then deleted too.
03:56
Alright.
03:57
That's the most wordiest column in our database migration for here.
04:00
So the next ones are gonna be simple.
04:02
We just need a string.
04:04
And in this case, this is just what it says.
04:06
It is a string of characters that we can enter into our database.
04:10
The first parameter is going to be what that name is.
04:12
I'm going to say this is a message, and then we can pass an optional
04:16
parameter of how much this string a max characters should it have.
04:22
And we're gonna say this is 255.
04:24
And then like you might have seen, Laravel already provides the timestamps
04:27
and ID columns automatically generated for this migration, which is great.
04:32
Outta the box.
04:33
We don't have to touch this.
04:34
This timestamps is a created at and an updated at column.
04:38
So we might even see that in our database right here where I was to go
04:42
into something like our users, we have a created at and an updated at timestamp.
04:47
Back to the chirps table.
04:48
Now how do we make this migration file that we created actually
04:53
then exists in our database?
04:55
Well, it's simple.
04:56
We open up our command line again and we type PHP, artisan Migrate.
05:02
And you see here, it created that chirps table, or it actually,
05:05
it ran the migration, which in turn created the chirps table.
05:09
This is a schema that created the chirps table with these particular columns.
05:14
Now that we have our migration entered into the database, we have that new table.
05:19
There's different ways that we can interact with the database before
05:22
we create any UI elements to be able to interact with the database on
05:26
our web application, we can, uh, do interactions with the database manually.
05:32
Now, this is where the AI tooling that Laravel provides
05:34
as a first party extension.
05:36
Laravel Boost is fantastic.
05:38
It has, uh, tools out of the box to be able to have your AI
05:42
interact with your database using the tools that Laravel expects.
05:47
What does that look like?
05:48
Well, Laravel has tinker, which is PHP Artisan Tinker.
05:51
What this does is allow you to interact with your database using Laravel command.
05:57
So I could say something like, uh, DB Select, and we're going to
06:01
select, and this is raw SQL queries.
06:03
We could say something like, select a star from Chirps.
06:10
And yeah, there's nothing there because we haven't added any chirps yet.
06:14
But there's other ways to interact with your database.
06:19
You might have seen, I already pulled up this database of SQL Light and VS.
06:23
Code and other IDs might have a database viewer extension that you
06:28
can install, open up and be able to interact with the database there.
06:32
And while most of these tools that are built into IDs or extensions for IDs like
06:38
VS code, they're usually just great for viewing things that are in your database
06:42
and that is handy but there's also another visual approach, like a Table
06:46
Plus or something like D Beaver or any other GUI editors for a database where
06:54
you can point it to your database file and then be able to interact with it.
06:58
For example, I could create my own chirp manually within this table plus GUI.
07:04
Now I'm discarding all those changes because we don't necessarily need to
07:06
interact with the database manually.
07:08
For right now, it's just helpful to know that either using AI or a tool
07:12
or even something like PHP Artisan Tinker, we could use these tools to
07:18
create new chirps in the database before we even create code to do that.
07:23
One thing I did wanna point out, we create this foreign ID for a user id.
07:27
Table.
07:27
But you might be thinking, Hey, we didn't actually create that migration.
07:32
Right?
07:32
Well, that's something that Laravel gives us out of the box.
07:35
And you saw that we had that user's table in our database, SQL Light Viewer.
07:40
So if we were to click into that, create users migration,
07:44
we're creating a user's table.
07:46
With a string of name, a string of email that has to be unique.
07:49
And all of this is pretty readable for us.
07:51
We have a timestamp that is email verified act, which could be knowable,
07:56
and then a string of password,
07:57
so there's a bunch of different tables that are created in this one migration,
08:01
but it's helpful to know that Laravel does provide some of these tables
08:05
out of the box, including users.
08:07
So that's why we didn't create our own users table migration.
08:12
It's just automatically using what Laravel set up.
08:14
Now before we continue, I do want to note that Tinker can be
08:17
used with what we call eloquent.
08:20
This is Elle's way of interacting with the database in a more clean matter.
08:25
Now this isn't necessary to grasp all at once.
08:28
It's just helpful to know that there are other ways of interacting with
08:32
the database other than using that DB facade, in this case, using, uh, select
08:38
queries that has sequel language.
08:40
And that might be confusing for you, but it's just helpful to know that
08:44
there is a more eloquent, and that's actually the name of the tool that
08:49
we interact with the database within Laravel of being able to select or
08:53
even create things within our database.
08:56
Again, you don't have to worry too much about everything that
08:59
you're learning right now.
09:00
We're gonna talk about it in more depth later.
09:03
But for your first Laravel application, just know that there are easier ways
09:08
to do almost everything within Laravel.
09:10
And before we move forward, I do want to manually create a chirp with PHP
09:14
Artisan Tinker, mostly to show you that there's an easier way to do it in the
09:18
next lesson, an easier way to interact with our database, even with the tools
09:23
that Laravel gives us through models.
09:26
But that's for next lesson, but also to show you that tinker or any way that
09:31
we're interacting with our database is a great use case for something like AI.
09:35
Within Laravel Boost, there's tools that allow you to work with Tinker or allow
09:40
your AI assistance to work with Tinker.
09:43
. You don't need to know all of these syntax for how to interact with the
09:46
database through Tinker, but it's helpful to know what your AI, or
09:51
even what specific commands might do.
09:54
I'm gonna type this all out here and then later paste it into Tinker.
09:58
So we have DB table chirps.
10:00
So we're entering into the chirps table for selecting the chirps
10:04
table and then inserting a message of my first chirp in the database.
10:09
And because we don't have a user, we can just leave it off of this DB table.
10:14
The DB is a facade that Laravel gives us to more easily interact with the
10:19
database instead of having to write those SQL queries that we wrote previously.
10:24
But we do have to put created at and updated at as timestamps 'cause
10:28
Laravel doesn't give those by default.
10:30
I'm going to clear this out, copy it, and then in PHP Artisan tinker,
10:35
I'm just going to paste that in and press enter and we get this true back.
10:41
So that means that this was successful, this chirp was
10:45
now entered into the database
10:47
so we could pull up our database,
10:49
see this chirp and see here, yes, this message was created,
10:54
my first chirp in the database.
10:57
But we can also do that in Tinker as well.
11:00
We could say DB table, shes get.
11:05
And there we go.
11:06
Here's our first chirp.
11:08
Congratulations.
11:09
You just entered something into the database using a command line tool.
11:13
I'm going to exit from Tinker.
11:14
There's two commands I want to make you aware of.
11:17
Within the PHP artisan, uh, namespace, that's migrate fresh, which means
11:24
if you absolutely made a mistake, or maybe you just need to change
11:27
an existing file, which is not the best way to do it, but if you're not
11:31
production, you can do whatever you want.
11:33
The PHP Artisan migrate Fresh will drop everything and then
11:37
create everything from scratch.
11:39
So in this case, we don't have that chirp that we just created.
11:43
Another one would be PHP Artisan Migrate Rollback.
11:46
Now, if we created a new migration in, in this case, maybe the chirps
11:50
table, and we wanted to roll that back, it would run the down structure.
11:56
If I was to go into that chirp table migration.
11:59
We have this down structure, and here this is going to drop the chirps table.
12:04
It's going to run this migration.
12:06
If we ran this.
12:07
Migrate rollback.
12:09
So if I do that, because we ran everything, we now don't
12:13
have anything in our database.
12:15
So I'm gonna run PHP Artisan migrate again.
12:18
So you now have a real database with the ability to create
12:23
real things in that database.
12:24
In this case, chirps, because we gave it a table.
12:26
We gave it a proper structure, in this case, a message, and
12:29
then a relationship to users.
12:32
And next lesson we'll dive into what does that relationship actually mean.
12:37
This is where that M of MVC comes into play, the model structure.
12:42
So if you've thought that this is a little bit confusing because working with, uh,
12:46
queries and stuff like that within a database can be a little bit confusing.
12:50
Next lesson is going to make everything a lot easier, so stick around.