2017 © Pedro Peláez
 

library reanimate

Undo Laravel soft deletes

image

mpociot/reanimate

Undo Laravel soft deletes

  • Thursday, March 19, 2015
  • by mpociot
  • Repository
  • 6 Watchers
  • 120 Stars
  • 434 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 6 Forks
  • 1 Open issues
  • 3 Versions
  • 13 % Grown

The README.md

Reanimate, (*1)

, (*2)

Restoring models in laravel is easy. Simply call restore on the soft-deleted model and you're good to go. But what if you want to implement a simple undo mechanism in your application?, (*3)

You need to take care of restoring the model, redirecting back, showing a success/error message..., (*4)

Wouldn't it be nice if this process could be simplified?, (*5)

Reanimate is a laravel package that allows you to do just that. It simplifies undoing of soft-deletes for your application., (*6)

Installation

Reanimation can be installed via composer, the details are on packagist, here., (*7)

To download and use this package, add the following to the require section of your projects composer.json file:, (*8)

"mpociot/reanimation": "1.*",

Run composer update to download the package, (*9)

php composer.phar update

That's it. Take a look at the implementation guide, to get started., (*10)

Docs

, (*11)

What Reanimate does

A simplified deletemethod on your controller might look like this:, (*12)

public function delete( User $user )
{
    $user->delete();
    return Redirect::route( "userIndex" )->with( "message", "userDeleted" );
}

So how would you undo that delete call? You need to create a route, pass that object id, resolve the object, restore it if it exists and finally redirect back., (*13)

With Reanimate, this becomes:, (*14)

public function delete( User $user )
{
    $user->delete();
    return Redirect::route( "userIndex" )->with( "message", "userDeleted" )->with( $this->undoFlash( $user ) );
}

undoFlash passes an array to your session with the following data:, (*15)

"undo" => [
    "route"  => "userUndo",
    "params" => [ "DELETED_MODEL_ID" ],
    "lang"   => "user.undo.message"
]

So if your session has an undo array, you know that you should present your users a possibility to undo the deletion., (*16)

Just make sure that the undo route, points to the undoDelete method, available through the Reanimate Trait., (*17)

This method will then restore the model with the given ID and will redirect the user to a given index route., (*18)

, (*19)

Implementation & configuration

Every controller in your application, that currently takes care of deleting a model and now should benefit from Reanimate, needs to use the ReanimateModels Traits., (*20)

For example, (*21)

namespace App\Http\Controllers;

class UserController extends Controller {
    use \Mpociot\Reanimate\ReanimateModels;
}

Deletes

When you redirect your users after a successful delete call, simply append the ->with( $this->undoFlash( $deletedModel ) ); data to your redirect., (*22)

undoFlash will automatically do two things for you:, (*23)

Auto generate an undo route:, (*24)

When no custom undo route is specified, Reanimate generates a named route by using the model name + "Undo"., (*25)

Example model names and undo routes:, (*26)

User -> userUndo, (*27)

Category -> categoryUndo, (*28)

FileEntry -> fileEntryUndo, (*29)

Auto generate an undo language key:, (*30)

By default, a lang key can be used within your views, for the undo action. This key is a lowercase representation of your model name + .undo.message, (*31)

Example model names and lang keys:, (*32)

User -> user.undo.message, (*33)

Category -> category.undo.message, (*34)

FileEntry -> fileentry.undo.message, (*35)

Restores

The easiest way to restore your models, is to add a named route to your routes.php that matches the generated undo route name., (*36)

This route needs to point to the undoDelete method of your controller., (*37)

This method takes care of restoring the model with the given primary key and returns a redirect to an auto generated index route., (*38)

Auto generated model name:, (*39)

Since this method only receives the ID of your model, but not the model itself, Reanimate tries to guess the correct model name for you., (*40)

It's done by using the singular version of your Controller's name., (*41)

Example controller names and the matching model names:, (*42)

UserController -> User, (*43)

CategoriesController -> Category, (*44)

FileEntryController -> FileEntry, (*45)

Auto generated index route:, (*46)

When no custom index route is specified, Reanimate generates a named route by using the model name + "Index"., (*47)

Example model names and undo routes:, (*48)

User -> userIndex, (*49)

Category -> categoryIndex, (*50)

FileEntry -> fileEntryIndex, (*51)

The redirect will also contain a flash data named message that contains either:, (*52)

modelname.undo.restored on success or modelname.undo.invalid when no model with the given ID could be found., (*53)

Customization

Don't like the auto generated routes? Don't like the auto generated model names? No problem!, (*54)

Simply override them in your controller class like this:, (*55)

namespace App\Http\Controllers;

class UserController extends Controller {
    use \Mpociot\Reanimate\ReanimateModels;

    protected $undoDeleteModel = 'This\Is\My\Custom\Model';

    protected $indexRoute = 'home';

    protected $undoRoute = 'ohNooooo';

}

You can also write your own undoDelete method, if you want some more control:, (*56)

namespace App\Http\Controllers;

class UserController extends Controller {
    use \Mpociot\Reanimate\ReanimateModels;

    public function myCustomUndoMethod( $primaryKey )
    {
        return $this->restoreModel( $primaryKey , new User(), "myCustomIndexRoute" );
    }

}

, (*57)

Contributing

Contributions are encouraged and welcome; to keep things organised, all bugs and requests should be opened in the github issues tab for the main project, at mpociot/reanimate/issues, (*58)

All pull requests should be made to the develop branch, so they can be tested before being merged into the master branch., (*59)

The Versions

19/03 2015
18/03 2015