larave-restore-banner-image

Como usuarios, estoy seguro que más de una vez les ha ocurrido que en alguna aplicación borraron o eliminaron algún registro por accidente y perdieron alguna información valiosa o alguna transacción importante y al final todo acabó siendo un desastre.

Como programadores debemos ser conscientes de estos posibles eventos y brindar a nuestros usuarios la posibilidad de corregirlos en el momento de una forma fácil y rápida, evitando toda clase de malestares que pueda generar la pérdida de información.

 Eloquent restore()

Usando Eloquent se puede recuperar un modelo eliminado (“soft-deleted”) haciendo uso del método restore().

$user = User::find(1);
$user->delete();
$user->restore();

Podemos escribir nuestro propio método para indicarle al usuario que puede restaurar el registro que acaba de eliminar.

Con el ejemplo de hoy aprenderás a usar correctamente esta funcionalidad y te aseguro que al aplicarla a tus proyectos tus usuarios quedarán sorprendidos y muy agradecidos por ello.

 Crear un nuevo modelo

Vamos a crear una pequeña agenda de contactos con nombre, teléfono y dirección de correo electrónico.

Iniciamos creando el modelo llamado Contact

php artisan make:model Contact

Editar la migración Contact

Debemos editar el archivo para agregar los campos requeridos a la base de datos, si eres nuevo con el tema de migraciones puedes visitar la clase Creando migraciones en laravel 5

<?php

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

class CreateContactsTable extends Migration {

  /**
  * Run the migrations.
  *
  * @return void
  */

public function up()
{
   Schema::create('contacts', function(Blueprint $table)
     {
           $table->increments('id');
           $table->string('full_name');
           $table->string('phone_number');
           $table->string('email');
           $table->softDeletes();
           $table->timestamps();
      });

}



  /**
  * Reverse the migrations.
  *
  * @return void
  */

  public function down()
  {
     Schema::drop('contacts');
  }
}

En este caso hacemos uso de un nuevo método predefinido por Laravel llamado softDeletes() que debe incluirse en todas las tablas sobre las cuales queremos usar restore();

 Preparando el modelo para usar restore()

Laravel requiere de una configuración adicional en el modelo que le permita trabajar con el sistema de recuperación de datos, esto lo hacemos agregando una variable $dates con el campo deleted_at que definimos anteriormente en la migración

<?php namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Contact extends Model {


   use SoftDeletes;

   protected $table = 'contacts';
   protected $dates = ['deleted_at'];
   protected $fillable = ['full_name', 'phone_number','email'];


}

Uso del componente Faker para agregar datos de prueba

No voy a entrar en detalle sobre el uso de este componente ya que hay una clase dedicada a Seeders y el componente Faker en Laravel 5

En este caso se crean 10 registros de prueba para el modelo Contact

<?php

use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

class ContactTableSeeder extends Seeder {

  /**
  * Run the contact table seeds.
  *
  * @return void
  */

  public function run()
  {
       $faker = Faker::create();
       for ($i=0; $i < 10; $i++) {
         \DB::table('contacts')->insert(array (
           'full_name' => $faker->name,
           'phone_number' => $faker->phoneNumber(),
           'email' => $faker->email
         ));

          }
  }
}

No olvides agregar la clase ContactTableSeeder para su ejecución en DatabaseSeeder.php

<?php


use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;


class DatabaseSeeder extends Seeder {


  /**
  * Run the database seeds.
  *
  * @return void
  */

  public function run()
  {
     Model::unguard();
     $this->call('ContactTableSeeder');
  }
}

Migrar base de datos y llenar con datos de prueba

En este punto podemos ejecutar la migración y el seeder para pasar a trabajar con el controlador.

php artisan migrate --seed

Crear una vista

Contamos en este momento con información en nuestra base de datos, el siguiente paso es poder visualizarla, para ello creamos una vista llamada list.blade.php

@extends('app')

@section('content')

<div class="container">
  <div class="row">
    <table class="table table-condensed table-striped table-bordered">
           <thead>
               <tr>
                 <th>Name</th>
                 <th>Phone</th>
                 <th>Email</th>  
                 <th>Action</th>
               </tr>
           </thead>
           <tbody>
               @foreach($contacts as $contact)
               <tr>
                   <td>{{ $contact->full_name }}</td>
                   <td>{{ $contact->phone_number }}</td>
                   <td>{{ $contact->email }}</td>
                   <td> <a href="{{ route('contact/delete', [$contact->id]) }}" class="btn btn-danger btn-xs">Delete</a>
                   </td>
               </tr>
               @endforeach
           </tbody>
       </table>
  </div>
</div>

@endsection

Nota: esta vista extiende de app.blade.php, recuerda que esa plantilla viene construida por defecto con la primera instalación de Laravel.

 Creando rutas

En este caso vamos a eliminar, recuperar y ver la lista de los contactos agendados

Route::get('contact', ['as' => 'contact', 'uses' => 'ContactController@index']);
Route::get('contact/delete/{id}', ['as' =>  'contact/delete', 'uses' => 'ContactController@destroy']);
Route::get('contact/restore/{id}', ['as' =>  'contact/restore', 'uses' => 'ContactController@restore']);

Métodos de la clase ContactController

Se definen los métodos a los que apuntan las rutas que acabamos de crear.

<?php namespace App\Http\Controllers;



use App\Http\Requests;

use App\Http\Controllers\Controller;
use App\Contact;
use Illuminate\Http\Request;

class ContactController extends Controller {

  /**
  * Display a listing of the resource.
  *
  * @return Response
  */
  public function index()
  {
    $contacts = Contact::all();
    return \View::make('list' , compact('contacts'));
  }


  /**
  * Remove the specified resource from storage.
  *
  * @param  int  $id
  * @return Response
  */

  public function destroy($id)
  {
    $contact = Contact::find($id);
    $contact->delete();
    return \Redirect::route( "contact" )->with("deleted" , $id );
  }



  /**
  * restore the specified resource to storage.
  *
  * @param  int  $id
  * @return Response
  */

   public function restore( $id )
   {
       //Indicamos que la busqueda se haga en los registros eliminados con withTrashed

       $contact = Contact::withTrashed()->where('id', '=', $id)->first();

       //Restauramos el registro
       $contact->restore();

       return \Redirect::route( "contact" )->with("restored" , $id );
   }

}

Notese que en los métodos destroy y restore pasamos una variable a la vista, esto se hace con el fin de comprobar la acción realizada y mostrar un mensaje en pantalla, para ello editamos nuevamente el archivo list.blade.php

@extends('app')

@section('content')

<div class="container">

   @if (Session::has('deleted'))
     <div class="alert alert-warning" role="alert"> Contacto borrado, si desea deshacer el cambio <a href="{{ route('contact/restore', [Session::get('deleted')]) }}">Click aqui</a> </div>
   @endif

   @if (Session::has('restored'))
     <div class="alert alert-success" role="alert"> Contacto restaurado</div>
   @endif

  <div class="row">
    <table class="table table-condensed table-striped table-bordered">
           <thead>
               <tr>
                 <th>Name</th>
                 <th>Phone</th>
                 <th>Email</th>  
                 <th>Action</th>
               </tr>
           </thead>
           <tbody>
               @foreach($contacts as $contact)
                 <tr>
                   <td>{{ $contact->full_name }}</td>
                   <td>{{ $contact->phone_number }}</td>
                   <td>{{ $contact->email }}</td>
                   <td> <a href="{{ route('contact/delete', [$contact->id]) }}" class="btn btn-danger btn-xs">Delete</a>
                   </td>
               </tr>
               @endforeach
           </tbody>
       </table>
  </div>
</div>
@endsection

Ahora al eliminar un registro veremos un mensaje en la parte superior con la opción de restaurarlo nuevamente

laravel-restore

Puedes aprender mucho más visitando los siguientes enlaces:

 

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Crear un Thumbnail con Laravel 5 y Bootstrap Lección siguiente Obtener videos de Youtube - Laravel 5