In this post, we will create the edit page, we will also give the possibility to delete posts to its creators and, finally, we will explain and use the soft deletes.
Edit
First, let’s create the posts editing page. Open the view posts.blade.php and add the link inside the loop that shows the posts. We are going to restrict that only the link can be viewed, if the user who created the post is the same one that is logged in.
1 2 3 |
@if (Auth::check() && $post->user_id == Auth::id()) <a href="{{URL::to('/')}}/post/{{ $post->id }}/edit">Edit</a> @endif |
Now we have to create the routes in the routes file. One route is the one that shows the view with the inputs (GET) and the other one (PATCH) is the one that updates the data:
1 2 |
Route::get('/post/{id}/edit', 'PostsController@edit'); Route::patch('/post/{id}', 'PostsController@update')->name('posts.update'); |
We are giving the route a name because later we will use it in the edit form.
Once we have the routes, we have to create the methods to which the routes refer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public function edit(Request $request) { $post = Post::findOrFail($request->id); return view('post_edit', ['post' => $post]); } public function update(PostRequest $request) { $post = Post::findOrFail($request->id); $post->update([ 'title' => $request->title, 'body' => $request->body ]); return redirect('posts'); } |
The first method (edit) what it does is according to the id that is passed, send the data to the view to show them in the inputs, if it doesn’t find any posts with that id, it shows an error.
The second method updates the post with the data sent from the inputs of the view and redirects to the list.
We need to create the edit view, we are going to create it, it will be called post_edit.blade.php and will contain:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@extends('layouts.app') @section('content') @include('includes.errors') {{ Form::model($post, ['route' => ['posts.update', $post->id], 'method' => 'PATCH']) }} <p>{{ Form::text('title', old('title')) }}</p> <p>{{ Form::textarea('body', old('body')) }}</p> <p>{{ Form::submit('Save', ['name' => 'submit']) }}</p> {{ Form::close() }} @endsection |
If you notice, we are showing the form another way. We are doing it with the classes provided by the HTML & Forms package. We pass the $post variable so that it shows in the inputs the information that is in the database and will be sent to the route called posts.update with the id of the post through the HTTP PATCH method.
With this we could edit the posts, but there is problem when the title is not edited. In our validation we put the title has to be unique, then if it doesn’t change, it detects that it already exists and we will see an error. To solve this, we have to edit the PostRequest and change the title validation line:
1 2 3 |
... 'title' => 'required|unique:posts,title,'.$this->id.'|max:255', ... |
Delete
We add this code below the edit link in the view:
1 2 3 4 5 6 |
<form action="{{URL::to('/')}}/post/{{ $post->id }}" method="POST"> {{ csrf_field() }} {{ method_field('DELETE') }} <button type="submit">Delete</button> </form> |
Add the route:
1 |
Route::delete('/post/{id}', 'PostsController@destroy'); |
Create the method in the controller:
1 2 3 4 5 6 |
public function destroy(Request $request) { $post = Post::findOrFail($request->id); $post->delete(); return redirect('posts'); } |
And now the users can delete their posts.
We update the middlewares to restrict the access to some users (the ones aren’t logged in and those who aren’t creators of the post).
Note: this can be done in other ways that are better, (for example, with policies that we will deal with in the next post).
1 2 3 4 |
public function __construct() { $this->middleware('auth', ['only' => ['store', 'edit', 'update', 'destroy']]); $this->middleware('owner', ['only' => ['edit', 'update', 'destroy']]); } |
Soft delete
So they are permanently removed from the database, Laravel has a function that is very simple to add that avoids that. It simply marks them as deleted, but doesn’t delete the record. This is known as Soft delete.
First of all, like always when we have to modify the structure of the database, we must create a migration:
1 |
php artisan make:migration add_softdelete_to_posts |
Open the file and add this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddSoftdeleteToPosts extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('posts', function(Blueprint $table) { $table->softDeletes(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('posts', function(Blueprint $table) { $table->dropSoftDeletes(); }); } } |
Execute the migration:
1 |
php artisan migrate |
When we have the field, simply, we have to add these lines to the model Post.php to activate soft deletes:
1 2 3 4 5 6 7 8 |
//above the file use Illuminate\Database\Eloquent\SoftDeletes; ... use SoftDeletes; protected $dates = ['deleted_at']; ... |