What to expect in the next generation of Laravel Forge. Read the blog post
Rewatch this lesson
Courses
/
Getting Started with Laravel
/
Edit and delete Chirps

Edit and delete Chirps

Getting Started with Laravel

Edit and delete Chirps
Complete CRUD operations by adding edit and delete functionality. Learn about RESTful routing and build a full-featured content management system.

No one's perfect and everyone makes mistakes, typos, you name it. So let's start the day with a nice cup of coffee and add the ability for our users to edit their chirps.

The neat part is this completes the whole CRUD operations within an MVC structure in a Laravel application. So CRUD: Create, Read, Update, and Delete. We've got Create and Read down—now let's do the Update and Delete parts!

Step 1: Add Edit and Delete UI

In our chirp.blade.php component (that's our component for each chirp that we're looping through), let's add edit and delete buttons. We'll add the UI first, but we won't hook it up just yet.

Update resources/views/components/chirp.blade.php:

1@props(['chirp'])
2 
3<div class="card bg-base-100 shadow">
4 <div class="card-body">
5 <div class="flex space-x-3">
6 @if ($chirp->user)
7 <div class="avatar">
8 <div class="size-10 rounded-full">
9 <img src="<https://avatars.laravel.cloud/>{{ urlencode($chirp->user->email) }}"
10 alt="{{ $chirp->user->name }}'s avatar" class="rounded-full" />
11 </div>
12 </div>
13 @else
14 <div class="avatar placeholder">
15 <div class="size-10 rounded-full">
16 <img src="<https://avatars.laravel.cloud/f61123d5-0b27-434c-a4ae-c653c7fc9ed6?vibe=stealth>"
17 alt="Anonymous User" class="rounded-full" />
18 </div>
19 </div>
20 @endif
21 
22 <div class="min-w-0 flex-1">
23 <div class="flex justify-between w-full">
24 <div class="flex items-center gap-1">
25 <span class="text-sm font-semibold">{{ $chirp->user ? $chirp->user->name : 'Anonymous' }}</span>
26 <span class="text-base-content/60">·</span>
27 <span class="text-sm text-base-content/60">{{ $chirp->created_at->diffForHumans() }}</span>
28 </div>
29 
30 <div class="flex gap-1">
31 <a href="/chirps/{{ $chirp->id }}/edit" class="btn btn-ghost btn-xs">
32 Edit
33 </a>
34 <form method="POST" action="/chirps/{{ $chirp->id }}">
35 @csrf
36 @method('DELETE')
37 <button type="submit"
38 onclick="return confirm('Are you sure you want to delete this chirp?')"
39 class="btn btn-ghost btn-xs text-error">
40 Delete
41 </button>
42 </form>
43 </div>
44 </div>
45 <p class="mt-1">{{ $chirp->message }}</p>
46 </div>
47 </div>
48 </div>
49</div>

Notice a few important things here:

  • Edit button: We're passing in the chirp ID. We want to target a particular, singular chirp, and this is a way to do that within Blade. The route looks like /chirps/{chirp_id}/edit.

  • Delete form: We have another form with @csrf and @method('DELETE'). This is necessary because HTML forms don't have a standard method of delete, so Laravel gives us this handy directive.

  • Confirmation: Notice that "onclick" on the delete button—it pops up with a browser modal asking "Are you sure you want to delete this chirp?" Just a neat little touch!

This might seem a little bit complicated, but bear with me. Most of everything we're going to look at when it comes to editing and deleting means that we have to do it within a single instance of a chirp. That's why we have this chirp ID inputted into these routes—because we need to find which chirp we need to edit and which chirp we need to delete.

Step 2: Add Routes

In our web routes, we can just continue to add those route parameters. Let's add routes for edit, update, and delete:

1use App\Http\Controllers\ChirpController;
2 
3Route::get('/', [ChirpController::class, 'index']);
4Route::post('/chirps', [ChirpController::class, 'store']);
5Route::get('/chirps/{chirp}/edit', [ChirpController::class, 'edit']);
6Route::put('/chirps/{chirp}', [ChirpController::class, 'update']);
7Route::delete('/chirps/{chirp}', [ChirpController::class, 'destroy']);

Notice those curly brackets with {chirp}? This is what we call route model binding. We know that we need to get an instance of a chirp, so this just gives Laravel an easy way of saying "Hey, within this route we need to look for something that we can identify as a chirp."

Now, Laravel does have a shorthand so that you don't have to do all of this. We're doing things a little bit differently just because we have a GET in the root directory and not a GET of /chirps. But what we could do is something like this:

1Route::get('/', [ChirpController::class, 'index']);
2 
3Route::resource('chirps', ChirpController::class)
4 ->only(['store', 'edit', 'update', 'destroy']);

This resource route is identical to the four routes we wrote out explicitly above—just an easier way of putting it. For right now, I'm going to be extremely explicit so you can see exactly what's happening.

Step 3: Create the Edit View

Now let's create the edit view that we will need because we are getting a new route /chirps/{chirp}/edit. In our views directory, since we don't actually have a directory for chirps (because our chirp index is technically the index of our whole application), I'm going to create one: chirps, and then in that chirps directory, we're going to have edit.blade.php.

Create a new file resources/views/chirps/edit.blade.php:

1<x-layout>
2 <x-slot:title>
3 Edit Chirp
4 </x-slot:title>
5 
6 <div class="max-w-2xl mx-auto">
7 <h1 class="text-3xl font-bold mt-8">Edit Chirp</h1>
8 
9 <div class="card bg-base-100 shadow mt-8">
10 <div class="card-body">
11 <form method="POST" action="/chirps/{{ $chirp->id }}">
12 @csrf
13 @method('PUT')
14 
15 <div class="form-control w-full">
16 <textarea
17 name="message"
18 class="textarea textarea-bordered w-full resize-none @error('message') textarea-error @enderror"
19 rows="4"
20 maxlength="255"
21 required
22 >{{ old('message', $chirp->message) }}</textarea>
23 
24 @error('message')
25 <div class="label">
26 <span class="label-text-alt text-error">{{ $message }}</span>
27 </div>
28 @enderror
29 </div>
30 
31 <div class="card-actions justify-between mt-4">
32 <a href="/" class="btn btn-ghost btn-sm">
33 Cancel
34 </a>
35 <button type="submit" class="btn btn-primary btn-sm">
36 Update Chirp
37 </button>
38 </div>
39 </form>
40 </div>
41 </div>
42 </div>
43</x-layout>

This is the same layout that we're using throughout our application. The majority of this form is exactly the same as our home.blade.php, just with different buttons and a different form action. This form is using the PUT method for the /chirps/{id} action, which goes to our update method in the web routes.

Notice this textarea needs to have the chirp that we need to edit, right? We're passing in the old message ({{ old('message', $chirp->message) }}) so that when we are directed to this edit page, we see the actual chirp message that exists within this chirp instance from the get-go.

Step 4: Implement Controller Methods

Now let's hook this up to our ChirpController. We need to add these methods. This edit method is showing the form for editing the specified resource. In a resource controller for a standard MVC Laravel application, this is just best practice.

1public function edit(Chirp $chirp)
2{
3 // We'll add authorization in lesson 11
4 return view('chirps.edit', compact('chirp'));
5}
6 
7public function update(Request $request, Chirp $chirp)
8{
9 // Validate
10 $validated = $request->validate([
11 'message' => 'required|string|max:255',
12 ]);
13 
14 // Update
15 $chirp->update($validated);
16 
17 return redirect('/')->with('success', 'Chirp updated!');
18}
19 
20public function destroy(Chirp $chirp)
21{
22 $chirp->delete();
23 
24 return redirect('/')->with('success', 'Chirp deleted!');
25}

Let me explain what's happening here:

Edit Method: Instead of using a string ID to find the existing chirp based off of maybe an ID, we can use route model binding. Because we know that the {chirp} parameter in our web routes is associated with the Chirp model, Laravel automatically assumes what chirp this is based off of that ID. We use the compact method to pass everything from this chirp into the view.

Update Method: This is similar to our store method where we need to validate something first and then update the chirp. We grab the chirp and update it with the validated info.

Destroy Method: We just delete the chirp and redirect back with a success message.

Step 5: A Note About Authorization

You might notice a few things when you test this out. Like we can edit anyone's chirp. Well, that's not necessarily good. And we'll fix that when authentication comes into play in the next couple of lessons.

Important: Right now, anyone can edit or delete any chirp. This isn't secure! In lesson 11, we'll add authentication so users can only edit and delete their own chirps. For now, we're focusing on getting the basic functionality working.

Step 6: Laravel Policies (Preview)

I do want to give a sneak peek on what this will look like when we do implement authorization and authentication. When a user is logged in, how do we know that they're able to edit and delete their own chirps?

Laravel has a clean way to put all the authorization code we might need with something called Policies. Here's a preview:

1php artisan make:policy ChirpPolicy --model=Chirp

In app/Policies/ChirpPolicy.php:

1public function update(User $user, Chirp $chirp): bool
2{
3 return $chirp->user()->is($user);
4}
5 
6public function delete(User $user, Chirp $chirp): bool
7{
8 return $chirp->user()->is($user);
9}

Then in your controller:

1public function update(Request $request, Chirp $chirp)
2{
3 if ($request->user()->cannot('update', $chirp)) {
4 abort(403);
5 }
6 // ... rest of method
7}

Or even simpler, we can use the authorize method:

1public function update(Request $request, Chirp $chirp)
2{
3 $this->authorize('update', $chirp);
4 // ... rest of method
5}

This $this->authorize() method will check: does this user have the authorization to delete this particular chirp? And in our ChirpPolicy, instead of returning false or true, we can just check if the chirp user is the user making the request: $chirp->user->is($user).

We can't put this in the controller just yet because we don't have authentication set up, but once we do, then we can add that back in!

We'll use this pattern once we add proper authentication!

Step 7: Add Edit Indication

Lastly, before we move on from this lesson, I want to change how something is shown when something is updated. If I edit a chirp, we don't know that this was actually edited. We don't know what the original was. It'd be nice to know that this was updated and not just posted some time ago.

Most social media platforms have this feature, so we might as well get ahead of it! Let's show when a chirp has been edited. Laravel automatically tracks both created_at and updated_at timestamps, so we can compare them to see if a chirp has been modified.

Update the chirp component (resources/views/components/chirp.blade.php) to show the edited indicator:

1<div class="flex items-center gap-1">
2 <span class="text-sm font-semibold">{{ $chirp->user ? $chirp->user->name : 'Anonymous' }}</span>
3 <span class="text-base-content/60">·</span>
4 <span class="text-sm text-base-content/60">{{ $chirp->created_at->diffForHumans() }}</span>
5 @if ($chirp->updated_at->gt($chirp->created_at->addSeconds(5)))
6 <span class="text-base-content/60">·</span>
7 <span class="text-sm text-base-content/60 italic">edited</span>
8 @endif
9</div>

If the chirp has been updated at, and if that updated_at is different than when the chirp was created_at by at least 5 seconds, then we'll show this little "edited" text. This checks if the updated_at timestamp is more than 5 seconds after created_at (to account for any small delays during creation).

When a chirp is edited, Laravel automatically updates the updated_at timestamp, and our component will show "edited" next to the timestamp. No database changes needed—Laravel's timestamps handle everything for us!

What We've Built

Things are really coming along! Your Chirper app now has full CRUD functionality:

  • Create - Users can post new chirps

  • Read - Display chirps in a feed

  • Update - Edit existing chirps with an edit form

  • Delete - Remove chirps with confirmation

  • Edit indication - Shows when chirps have been modified

We have a nice edit page that automatically knows what information to bring in thanks to route model binding. We can edit and delete chirps (though right now anyone can edit anyone's chirps, which we'll fix with authentication).

In the next lessons, we'll add proper authentication so users can actually register, log in, and manage their own chirps securely. We'll allow our users to register and create accounts, and you'll see how easy this can be even without a starter kit.

Ready to make this a real multi-user application? Let's add authentication!

00:00
No one's perfect and everyone makes mistakes, typos, you name it.
00:04
Uh, so if you don't want us just start the day with a nice cup of Kofi.
00:08
Maybe we should add the ability for our users to edit their chirps.
00:12
And the neat part is this completes the whole CRUD operations within A
00:17
MVC structure in a larva application.
00:20
So crud, create, read, update, and delete.
00:24
So let's do the update and delete parts.
00:26
Alright.
00:27
In our chirp blade php, that's our component for the chirp
00:31
that we are looping through.
00:32
Anytime we have new chirps, why don't we add the edit and delete.
00:36
Buttons first, as well as the form to do it.
00:38
We just won't hook it up just yet.
00:40
So this will probably go great after.
00:43
Yeah, probably after this timestamp.
00:45
I'm just going to add this in.
00:48
Now this is a edit button.
00:50
We're passing in the chirp id.
00:53
Now, this is helpful to know.
00:54
We want to target a particular, a singular chirp, and this is
00:59
a way to do that within Blade.
01:01
What this looks like is we are saying, Hey, we want to go to the slash chirps
01:06
route, but we need to pass in a chirp id, and then we're going to edit it.
01:12
We'll hook up how this works within our web route in just a little bit.
01:17
Next we do have another form.
01:19
Again, we do have to pass in that at csrf method, but this is
01:23
going to be a method of delete.
01:25
So we do have a method of post with a method of delete, and that is
01:29
necessary because H TM L forms do not have a standard method of delete.
01:35
So Laravel gives us this handy directive.
01:38
Similar to this route that we're showing up here.
01:40
To go to the edit form for our delete button, we have the action of slash
01:45
chirps, and again, passing in a chirp id.
01:49
All right.
01:49
This might seem a little bit complicated, but bear with me here.
01:53
Most of everything that we're gonna be taking a look at when it comes
01:56
to editing and when it comes to deleting means that we have to do it
02:00
within a single instance of a church.
02:02
And that's why we have this whole chirp id, uh, inputted into these
02:07
routes because we need to find which chirp we need to edit, and we need to
02:11
find which chirp we need to delete.
02:13
So why don't we, in our web routes, we can just continue to add those
02:17
route colon, colon parameters.
02:20
So we can do a route Git and we can do this for slash chirps slash, and
02:26
then we're going to add in a specific chirp id, and that happens within these
02:30
curly brackets saying that, Hey, we need a particular instance of a chirp.
02:35
And then I'm going to say that this is the edits, and just for now, I'm just going
02:39
to add the route puts and we're gonna do the exact same thing of chirps slash.
02:46
Chirp again in curly brackets.
02:48
And then the last one is going to be route delete, and that's
02:52
going to be slash chirps slash and then chirp in curly brackets.
02:57
Now we're going to add the actual controller methods to this so that they
03:01
actually function the way we want, but this curly bracket chirp is the exactly
03:06
the same thing that we are doing here.
03:08
This chirp within the curly brackets is what we would call route model binding.
03:13
We know that we need to get an instance of a chirp, and so this just gives
03:18
Laravel an easy way of saying, Hey, within this we need to look for something that
03:22
resembles, or we can identify as a chirp.
03:26
Now we're just gonna pass in those chirp controller classes.
03:30
So we're gonna say a chirp controller, and this will be the class with one
03:35
of, uh, let's go ahead and say, this is the edit one, and just for simplicity's
03:40
sake, I'm just going to do the rest.
03:42
update and destroy.
03:45
Now, Laravel does have a shorthand so that you don't have to do all of this.
03:49
And we're doing things a little bit differently just because we have a
03:53
git in the root directory and not a git of slash chirps, for example,
03:59
where we're listing all the chirps.
04:01
We're doing that all on one page.
04:02
But what we could do is something like this, we have a route resource where
04:07
we are resourcing because we have that resource controller and passing
04:11
that resource to chirp controller.
04:16
Class and then we could say, uh, we need to pass in everything, but only really
04:22
the store edits update and destroy.
04:30
And this is identical to these four right here.
04:34
Just an easier way of putting it.
04:36
For right now, I'm just going to be extremely explicit.
04:39
Now let's go ahead and create the edit view that we will need
04:42
because we are getting a new route slash chirps slash chirp.
04:47
This is that Route Model Binding and edits.
04:50
Why don't we create that in our file?
04:53
Views.
04:53
And then in view, since we don't actually have a directory for chirps, because
04:57
our chirp index is technically the index of our whole application, I'm going
05:02
to create one chirps, and then in that chirps directory, we're going to have
05:06
edit blade php, this created directory.
05:11
And then we have edit blade php.
05:13
I'm going to paste everything in that we have again on the laravel.com learn page.
05:19
You can find that for this lesson down below.
05:21
This is the same layout that we are using throughout our application.
05:25
We pass in a new slot title with Edit chirp, and the majority of this
05:29
form is exactly the same as our home do a PHP just with the different
05:35
buttons and a different form.
05:37
And this form we are using the.
05:38
Put method for that action.
05:41
Chirps id.
05:42
Well, where does this go to?
05:43
In our web route, we have the put chirps chirp.
05:46
This is the update method.
05:48
So that way instead of creating a new chirp, we're really just updating one.
05:52
And now this text area needs to have the chirp that we need to edit, right?
05:56
So we are passing in the old message, the chirp message., so that when we are
06:01
directed to this edit page, we see from the get go the actual chirp message
06:07
that exists within this chirp instance.
06:10
We're gonna be passing that chirp into the view within our
06:13
controller here in a little bit.
06:14
And then we have a cancel button that's just directing us home.
06:17
Why don't we hook this up to our chirp controller?
06:19
This would be in the public function edit method, which is showing the form
06:23
for editing the specified resource.
06:25
Again, in a resource controller for a standard MVC Lable application.
06:31
This is just best practice.
06:32
So we might say here we're going to return a view, and in that view we're going to
06:37
say that this is the chirps edit page.
06:40
And this.is going to say that this is in the directory of chirps.
06:44
Again, in our uh, views directory, we have the chirps directory.
06:50
We're going to use the edit page within there.
06:52
Now we do want to pass in the chirp, right?
06:55
Because in our web route we are getting these chirp route model binding.
07:00
In this case, we need the instance of the chirp in our edit blade php
07:04
because we need the chirp ID to be able to post back to whatever
07:09
chirp we're actually editing.
07:10
And then we also need the old message.
07:12
What is the message of the current chirp that we're editing
07:17
and here in chirp controller instead of the string of id?
07:20
Well, we could use this to kind of find the existing
07:24
chirp based off of maybe an id
07:27
maybe that Id helps us find that chirp, but we can use route model binding.
07:32
That's exactly what I kind of talked about here.
07:34
In this web routes, we have this chirp parameter, and because we know that
07:39
this is the chirp model associated with it, we can automatically assume what
07:44
chirp this is based off of that Id.
07:47
Because when we go into our chirp blade dot php, that's that chirp component,
07:52
and we wanted to edit a chirp.
07:53
We are passing in the chirp id.
07:55
So this is Laravel way of saying, instead of having to search the database
07:59
for a particular chirp, be with an id.
08:02
Laravel iss just going to do all this for us.
08:04
It's gonna look like this.
08:05
We're going to pass in the chirp model with a chirp, a variable.
08:10
And then we can use this compact method that's just saying, Hey, I want to pass
08:14
everything from this chirp into this view.
08:17
And there we go.
08:19
So what we're doing here is saying, when this edit method has a chirp
08:22
associated with it, a chirp model, let's just pass everything that is
08:25
associated to that chirp, into the view.
08:29
Again, create an array containing the variables and their values.
08:32
Oops.
08:32
It looks like this button is a little bit out of whack when it comes to our
08:35
styles, but if we click edit, you can see maybe here in the lower left side of the
08:40
screen that it's slash chirp slash seven.
08:43
Clicking on it, we get this view slash chirps slash seven.
08:47
That's the seventh chirp, and it automatically knows
08:49
what information to bring in.
08:52
I'm gonna cancel.
08:52
Let's fix this.
08:53
Just for simplicity's sake, I'm going to add a new diviv around these two
08:58
divs so that way we can separate them from the actual message and then we
09:03
can have this diviv be a class of flex with justified between with the full.
09:10
And then we do need this to take up the full space.
09:13
So flex of one, again, just a small change and yeah, that looks a lot better.
09:19
So now that we have this new edit page, let's go ahead and link
09:22
up this, uh, update chirp button as well as the delete button.
09:27
This is gonna be done in our chirp controller.
09:29
So first the update method.
09:31
Again, we want to pass in the CHIRP model, so we're going to use the chirp
09:35
model and it's going to be a chirp.
09:37
This is gonna be similar to our store where we need to validate something
09:40
first and then update the chirp.
09:44
So we're just gonna copy and paste this and then change it.
09:48
Instead of creating the chirp, what we're going to need to do is grab the chirp
09:52
and update it with the validated info.
09:55
And then instead of redirecting with the success of your chirp has been posted, we
10:00
can say, uh, your chirp has been updated.
10:03
Let's try this out.
10:04
Now I can finally fix this typo.
10:06
Update chirp.
10:07
Your chirp has been updated, and look at that.
10:10
Now you might notice a few things, and we'll get to them
10:12
in the next couple of lessons.
10:14
Like we can edit anyone's chirp.
10:16
Well, that's not necessarily good.
10:18
And we'll fix that when authentication comes into play
10:21
in the next couple of lessons.
10:22
First, let's go ahead and make this delete button work right now.
10:27
As you can tell, nothing happened.
10:29
One thing that's really cool to note that if you just copy and paste
10:33
it in, I wanted you to know that this is there in the delete button.
10:37
If we click on it, it pops up with a browser modal.
10:41
Are you sure you want to delete this chirp?
10:43
And of course, this isn't hooked up just yet, but this exists on the on click.
10:48
Method within a button.
10:50
We want to return a confirm.
10:51
This is just an HTML modal, an H, TM L, confirmation modal.
10:55
Are you sure you want to delete this chirp?
10:58
Just something neat.
10:59
All right.
10:59
In the chirp controller, we need to add this destroy method
11:04
again.
11:04
You guessed it.
11:05
We need the actual chirp first, and then we're just gonna say
11:08
that we can delete the chirp.
11:10
Why don't we return a redirect with the same kind of message saying that
11:15
this chirp has now been deleted,
11:20
trying this out.
11:22
Delete.
11:23
Okay.
11:25
Your chirp has been deleted.
11:27
But again, it's not very good if we can delete anyone's chirp.
11:31
We will get to authorization in a little bit and what that means, but I
11:35
do want to give a sneak peek on what this will look like when we do implement
11:39
authorization and authentication.
11:41
In this case, when a user is logged in, how do we know that they're able
11:45
to edit and delete their own chirps?
11:48
Let's start off by using an authorization check that Laravel gives.
11:52
It's something called a policy, and you guessed it.
11:54
We can use a PHP Artisan Command to make a policy.
11:59
Now we already have, uh, a chirp model that this policy should be modeled after,
12:05
and if we leave that blank, we can say that this is going to be the CHIRP policy.
12:11
And we need to apply this to the chirp model.
12:14
And there we go.
12:15
If we now look at this chirp policy, this gives us an idea of what can
12:20
actually happen within a chirp.
12:23
This is just a clean way to put all the code that we might need to check
12:27
if a user is able to do X, Y, or Z. And then in our chirp controller, we
12:33
can do something as simple as saying.
12:36
This
12:37
authorize, delete and passing in the chirp.
12:42
What this will do is it will say, um, has this authorized method of
12:47
delete for this particular chirp, does this user have the ability?
12:51
And in our chirp policy, uh, in the delete, it's returning false.
12:55
But I could say this is returning true instead.
12:59
And of course, we don't have a user just yet, but what this chirp controller is
13:04
now going to check is, does this user have the delete authorization to be
13:09
able to delete this particular chirp?
13:11
I just wanted to give a sneak peek on what this would look like.
13:14
As soon as we have users able to be creating chirps, deleting them,
13:18
editing them, it's as simple as this authorize, but then in our chirp policy,
13:24
making sure that this is correct.
13:27
instead of returning false or true, we really need to just
13:30
check is the user, the chirp user?
13:32
And because we have model relationships, it makes it easy.
13:35
We can say chirp user is user.
13:43
This is saying if the chirp user is the user that is trying to make
13:47
this request, then returning true.
13:49
If it's not, we're returning false, and we need the same for here as well.
13:54
Again, we can't put this in the chirp controller just yet, so we're going to
13:57
remove this authorization piece, but once we do set up authentication, then
14:01
we can add that back in for the destroy method as well as the update method.
14:06
lastly, before we move on from this lesson, I do want to change
14:10
how something is updated or shown when something is updated, rather.
14:15
So if I edit this and I say, if.
14:17
Wow, and I update this.
14:19
Well, we don't know that this was actually edited.
14:22
We don't know what the original was.
14:24
We don't necessarily need to worry about that, but it'd be nice to
14:27
know that this was updated and not just sent two hours ago.
14:30
I mean, most social media platforms have this problem at some point in time,
14:34
so we might as well get ahead of it.
14:36
In our chirp component,
14:38
in addition to the DIF for humans, we really just want to add this IF statement,
14:42
if the CHIRP has been updated at, and if that updated at is different than when the
14:47
chirp created at at least by five seconds.
14:51
Then why don't we show this little edited text?
14:54
And there we go.
14:55
This was posted two hours ago, but it was edited.
14:58
If I edit this one by our anonymous user,
15:01
new boast edited
15:03
things are really coming along.
15:04
Why don't, in the next lesson we add authentication, at least the
15:07
first piece of it, we're gonna allow our users to register to create new
15:11
accounts, and you'll see how easy this can be even without a starter kit.