Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Tutorial completo de exclusão suave e restauração de registros excluídos do Laravel 8


Originalmente postado em https://codeanddeploy.com visite e baixe o código de exemplo:
https://codeanddeploy.com/blog/laravel/complete-laravel-8-soft-delete-restore-deleted-records-tutorial

Nesta postagem, compartilharei com você uma exclusão reversível completa do Laravel 8 e restauração de registros excluídos tutorial. Ao desenvolver operações CRUD em Laravel, às vezes precisamos implementar soft deletes. Para que, se excluirmos incorretamente o registro específico, possamos restaurá-los facilmente. É por isso que isso é importante e deve existir em nosso aplicativo Laravel.



Neste artigo, você aprenderá um implemento completo com a exclusão reversível do Laravel e como restaurar os registros excluídos com exemplo.

Etapa 1:instalação do Laravel


Se você não tiver uma instalação do Laravel 8 em seu local, basta executar o seguinte comando abaixo:

composer create-project --prefer-dist laravel/laravel laravel-soft-delete

Uma vez feito acima, precisamos instalar o Pacote Coletivo Laravel, execute o seguinte comando abaixo:

composer require laravelcollective/html

Etapa 2:configuração do banco de dados


Se o seu projeto Laravel é novo, então você precisa atualizar suas credenciais de banco de dados. Basta abrir o arquivo .env em seu projeto Laravel 8.

.env


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name_here
DB_USERNAME=your_database_username_here
DB_PASSWORD=your_database_password_here

Etapa 3:configuração da migração


Vamos criar uma migração para nosso projeto de exemplo de **laravel soft delete **. Neste exemplo, estamos usando a tabela do usuário onde a migração já existe na instalação do Laravel. Então, só precisamos editar essa migração. Veja abaixo o código de atualização:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name')->nullable();
            $table->string('email')->unique();
            $table->string('username')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->softDeletes();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Como você pode ver, adicionamos o $table->softDeletes(); método para implementar a exclusão reversível do laravel.

Agora vamos executar o seguinte comando abaixo:

php artisan migrate

Etapa 4:configurar rotas


No meu exemplo, criarei manualmente minhas rotas brutas. Basta abrir o "routes/web.php" arquivo e adicione as seguintes rotas.

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::group(['namespace' => 'App\Http\Controllers'], function()
{   
    /**
     * Home Routes
     */
    Route::get('/', 'HomeController@index')->name('home.index');

    Route::group(['prefix' => 'users'], function() {
        Route::get('/', 'UsersController@index')->name('users.index');
        Route::get('/create', 'UsersController@create')->name('users.create');
        Route::post('/create', 'UsersController@store')->name('users.store');
        Route::get('/{user}/show', 'UsersController@show')->name('users.show');
        Route::get('/{user}/edit', 'UsersController@edit')->name('users.edit');
        Route::patch('/{user}/update', 'UsersController@update')->name('users.update');
        Route::delete('/{user}/delete', 'UsersController@destroy')->name('users.destroy');
        Route::post('/{user}/restore', 'UsersController@restore')->name('users.restore');
        Route::delete('/{user}/force-delete', 'UsersController@forceDelete')->name('users.force-delete');
        Route::post('/restore-all', 'UsersController@restoreAll')->name('users.restore-all');
    });
});

Como você pode ver, adicionamos as rotas de restauração, exclusão forçada e restauração de tudo. Você verá nosso código de controlador para essas rotas.

Etapa 5:configurar o modelo para nossa exclusão reversível


Como você pode ver abaixo, importamos o uso Illuminate\Database\Eloquent\SoftDeletes; class e use-o em nosso modelo User.

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;


class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable, SoftDeletes;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'username',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];

    /**
     * Always encrypt password when it is updated.
     *
     * @param $value
     * @return string
     */
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }
}

Etapa 6:Métodos do controlador de exclusão suave e restauração de registros excluídos do Laravel


Index dentro do UserController.php como você pode ver eu verifiquei se existe um status com o valor arquivado da requisição e chamei o método $users->onlyTrashed() para que apenas a exclusão reversível seja exibida nas listas.

/**
 * Display all users
 * 
 * @return \Illuminate\Http\Response
 */
public function index(Request $request) 
{
    $users = User::latest();

    if($request->get('status') == 'archived') {
        $users = $users->onlyTrashed();
    }

    $users = $users->paginate(10);

    return view('users.index', compact('users'));
}

Neste método dentro do UserController.php eu chamei o withTrashed() e restaurar() métodos isso nos permitirá restaurar o registro excluído.

/**
 *  Restore user data
 * 
 * @param User $user
 * 
 * @return \Illuminate\Http\Response
 */
public function restore($id) 
{
    User::where('id', $id)->withTrashed()->restore();

    return redirect()->route('users.index', ['status' => 'archived'])
        ->withSuccess(__('User restored successfully.'));
}


Esta é a implementação de forçado a excluir o registro na lixeira usando forceDelete() método.

/**
 * Force delete user data
 * 
 * @param User $user
 * 
 * @return \Illuminate\Http\Response
 */
public function forceDelete($id) 
{
    User::where('id', $id)->withTrashed()->forceDelete();

    return redirect()->route('users.index', ['status' => 'archived'])
        ->withSuccess(__('User force deleted successfully.'));
}

Nesta ação, chamamos o método onlyTrashed() e restaurar() métodos para que todos nós restauremos os registros que estão na lixeira.

/**
 * Restore all archived users
 * 
 * @param User $user
 * 
 * @return \Illuminate\Http\Response
 */
public function restoreAll() 
{
    User::onlyTrashed()->restore();

    return redirect()->route('users.index')->withSuccess(__('All users restored successfully.'));
}

Etapa 7:controlador de usuário de exclusão suave do Laravel


Abaixo está o código completo para o nosso UserController.php com implementações do Laravel 8 soft delete e restauração de registros deletados.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\StoreUserRequest;
use App\Http\Requests\UpdateUserRequest;

class UsersController extends Controller
{
    /**
     * Display all users
     * 
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request) 
    {
        $users = User::latest();

        if($request->get('status') == 'archived') {
            $users = $users->onlyTrashed();
        }

        $users = $users->paginate(10);

        return view('users.index', compact('users'));
    }

    /**
     * Show form for creating user
     * 
     * @return \Illuminate\Http\Response
     */
    public function create() 
    {
        return view('users.create');
    }

    /**
     * Store a newly created user
     * 
     * @param User $user
     * @param StoreUserRequest $request
     * 
     * @return \Illuminate\Http\Response
     */
    public function store(User $user, StoreUserRequest $request) 
    {
        //For demo purposes only. When creating user or inviting a user
        // you should create a generated random password and email it to the user
        $user->create(array_merge($request->validated(), [
            'password' => 'test' 
        ]));

        return redirect()->route('users.index')
            ->withSuccess(__('User created successfully.'));
    }

    /**
     * Show user data
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function show(User $user) 
    {
        return view('users.show', [
            'user' => $user
        ]);
    }

    /**
     * Edit user data
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function edit(User $user) 
    {
        return view('users.edit', [
            'user' => $user
        ]);
    }

    /**
     * Update user data
     * 
     * @param User $user
     * @param UpdateUserRequest $request
     * 
     * @return \Illuminate\Http\Response
     */
    public function update(User $user, UpdateUserRequest $request) 
    {
        $user->update($request->validated());

        return redirect()->route('users.index')
            ->withSuccess(__('User updated successfully.'));
    }

    /**
     * Delete user data
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user) 
    {
        $user->delete();

        return redirect()->route('users.index')
            ->withSuccess(__('User deleted successfully.'));
    }

    /**
     *  Restore user data
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function restore($id) 
    {
        User::where('id', $id)->withTrashed()->restore();

        return redirect()->route('users.index', ['status' => 'archived'])
            ->withSuccess(__('User restored successfully.'));
    }

    /**
     * Force delete user data
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function forceDelete($id) 
    {
        User::where('id', $id)->withTrashed()->forceDelete();

        return redirect()->route('users.index', ['status' => 'archived'])
            ->withSuccess(__('User force deleted successfully.'));
    }

    /**
     * Restore all archived users
     * 
     * @param User $user
     * 
     * @return \Illuminate\Http\Response
     */
    public function restoreAll() 
    {
        User::onlyTrashed()->restore();

        return redirect()->route('users.index')->withSuccess(__('All users restored successfully.'));
    }
}

Etapa 8:visualização da lâmina de índice


Codifique abaixo sobre nosso index.blade.php que codificamos as implementações de exclusão reversível do Laravel.

@extends('layouts.app-master')

@section('content')

    <h1 class="mb-3">Laravel Soft Delete Example - codeanddeploy.com</h1>

    <div class="bg-light p-4 rounded">
        <h1>Users</h1>
        <div class="lead">
            Manage your users here.
            <a href="{{ route('users.create') }}" class="btn btn-primary btn-sm float-right">Add new user</a>
        </div>

        <div class="mt-2">
            @include('layouts.partials.messages')

            <br>
            <a href="/users">All users</a> | <a href="/users?status=archived">Archived users</a>

            <br><br>
            @if(request()->get('status') == 'archived')
                {!! Form::open(['method' => 'POST','route' => ['users.restore-all'],'style'=>'display:inline']) !!}
                {!! Form::submit('Restore All', ['class' => 'btn btn-primary btn-sm']) !!}
                {!! Form::close() !!}
            @endif
        </div>

        <table class="table table-striped">
            <thead>
            <tr>
                <th scope="col" width="1%">#</th>
                <th scope="col" width="15%">Name</th>
                <th scope="col">Email</th>
                <th scope="col" width="10%">Username</th>
                <th scope="col" width="1%" colspan="4"></th>    
            </tr>
            </thead>
            <tbody>
                @foreach($users as $user)
                    <tr>
                        <th scope="row">{{ $user->id }}</th>
                        <td>{{ $user->name }}</td>
                        <td>{{ $user->email }}</td>
                        <td>{{ $user->username }}</td>
                        <td><a href="{{ route('users.show', $user->id) }}" class="btn btn-warning btn-sm">Show</a></td>
                        <td><a href="{{ route('users.edit', $user->id) }}" class="btn btn-info btn-sm">Edit</a></td>
                        <td>
                            @if(request()->get('status') == 'archived')
                                {!! Form::open(['method' => 'POST','route' => ['users.restore', $user->id],'style'=>'display:inline']) !!}
                                {!! Form::submit('Restore', ['class' => 'btn btn-primary btn-sm']) !!}
                                {!! Form::close() !!}
                            @else
                                {!! Form::open(['method' => 'DELETE','route' => ['users.destroy', $user->id],'style'=>'display:inline']) !!}
                                {!! Form::submit('Delete', ['class' => 'btn btn-danger btn-sm']) !!}
                                {!! Form::close() !!}
                            @endif
                        </td>
                        <td>
                            @if(request()->get('status') == 'archived')
                                {!! Form::open(['method' => 'DELETE','route' => ['users.force-delete', $user->id],'style'=>'display:inline']) !!}
                                {!! Form::submit('Force Delete', ['class' => 'btn btn-danger btn-sm']) !!}
                                {!! Form::close() !!}
                            @endif
                        </td>
                    </tr>
                @endforeach
            </tbody>
        </table>

        <div class="d-flex">
            {!! $users->links() !!}
        </div>

    </div>
@endsection

Agora você tem as implementações completas para a exclusão reversível do Laravel, incluindo a restauração de registros excluídos.

Espero que este tutorial possa ajudá-lo. Por favor, visite aqui https://codeanddeploy.com/blog/laravel/complete-laravel-8-soft-delete-restore-deleted-records-tutorial se você quiser baixar este código.

Boa codificação :)