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: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
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
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: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: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
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: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: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
In the chirp controller, we need to add this destroy method
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: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: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: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:55
This was posted two hours ago, but it was edited.
14:58
If I edit this one by our anonymous user,
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.