At QuickAdminPanel, our goal is to save developer’s time. Laravel Eloquent is a good example of this – its “magic” helps to get things done faster. But on top of that, there are a lot of packages that can help even more. Let’s review the most popular ones.

Notice: some of the packages have a similar (almost identical) packages created by other developers, I’ve added those links at the end of each package review, where applicable.


1. Laravel Auditing: Record the change log from models

URL: http://laravel-auditing.com

Package that saves changes of your Eloquent model records as so-called “audits”, in a separate DB table.
Usage is very simple. All you need to do in your model:

use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;

class Article extends Model implements Auditable
{
    use \OwenIt\Auditing\Auditable;

    // ...
}

And then you can get all “audits” by your model:

// Get first available Article
$article = Article::first();

// Get all associated Audits
$all = $article->audits;

// Get first Audit
$first = $article->audits()->first();

// Get last Audit
$last = $article->audits()->latest()->first();

// Get Audit by id
$audit = $article->audits()->find(4);

Official website: laravel-auditing.com
Article on Laravel News: Track Laravel Model Changes with Laravel Auditing

Similar package: VentureCraft/revisionable


2. laravel-soft-cascade: Cascade Delete & Restore when using Laravel SoftDeletes

URL: https://github.com/Askedio/laravel-soft-cascade

Soft-deletes is a great Eloquent function out-of-the-box, but it doesn’t work with foreign keys and ->onDelete(‘cascade’); migration. This package will solve that problem.

Usage. In your model use this:

use \Askedio\SoftCascade\Traits\SoftCascadeTrait;

protected $softCascade = ['profiles']; // names of your relations

After this, when you can soft-delete parent entry – all children entries will be automatically soft-deleted. It also works with restore() function:

User::first()->delete();
User::withTrashed()->first()->restore();

More info: Cascading SoftDeletes with Laravel 5

Similar package: michaeldyrynda/laravel-cascade-soft-deletes


3. spatie/laravel-schemaless-attributes: Add schemaless attributes to Eloquent models

URL: https://github.com/spatie/laravel-schemaless-attributes

This package provides a trait that when applied on a model, allows you to store arbritrary values in a single JSON column.

Preparing the model is a little more than one line of code, but still quite understandable, you need to define an attribute, accessor and scope:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\SchemalessAttributes\SchemalessAttributes;

class TestModel extends Model
{
    // ...

    public $casts = [
        'extra_attributes' => 'array',
    ];

    public function getExtraAttributesAttribute(): SchemalessAttributes
    {
        return SchemalessAttributes::createForModel($this, 'extra_attributes');
    }

    public function scopeWithExtraAttributes(): Builder
    {
        return SchemalessAttributes::scopeWithSchemalessAttributes('extra_attributes');
    }

}

And then you can just use this attribute as a property inside your model:

$yourModel->extra_attributes->name = 'value';
$yourModel->extra_attributes->name; // Returns 'value'

Or as an array:

// All existing schemaless attributes will be replaced
$yourModel->extra_attributes = ['name' => 'value'];
$yourModel->extra_attributes->all(); // Returns ['name' => 'value']

4. awssat/laravel-visits: Track Model Visits

URL: https://github.com/awssat/laravel-visits

This package allows you to log visits to some page/model. It does that using Redis, so you need to configure this:

'laravel-visits' => [
    'host' => env('REDIS_HOST', '127.0.0.1'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 3, // anything from 1 to 15, except 0 (or what is set in default)
],

And then you can log visits with one line of code:

visits($post)->increment();

Counting the posts is also easy:

visits($post)->count();

It also has a logic of limiting the visit logging once per IP every 15 minutes, but it’s also configurable.

The best part comes if you want to aggregate data:

visits($post)->countries(); // top countries
visits($post)->refs(); // referers
visits('App\Post')->top(10); // Top 10 posts

More on Laravel News: Count Models With the Laravel Visits Package


5. cybercog/laravel-love: React on Eloquent models with Likes or Dislikes

URL: https://github.com/cybercog/laravel-love

If you have posts or comments that may be liked/disliked, this package is for you.

Preparation for the model looks like this:

use Cog\Contracts\Love\Likeable\Models\Likeable as LikeableContract;
use Cog\Laravel\Love\Likeable\Models\Traits\Likeable;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements LikeableContract
{
    use Likeable;
}

And then you can do things like:

$user->like($article);
$article->likeBy(); // current user
$article->likeBy($user->id);

$user->unlike($article);
$article->unlikeBy(); // current user
$article->unlikeBy($user->id);

$article->likesCount; // get likes for article

$article->collectLikers(); // Get collection of users who liked model

More on Laravel News: Laravel Love: Likes and Dislikes for Eloquent Models


6. spatie/laravel-tags: Add tags and taggable behaviour to your Laravel app

URL: https://github.com/spatie/laravel-tags

The only thing you have to do is add the HasTags trait to an Eloquent model to make it taggable.

use Spatie\Tags\HasTags;

class NewsItem extends Model
{
    use HasTags;
    ...
}

And then feel free to use it:

//create a model with some tags
$newsItem = NewsItem::create([
   'name' => 'testModel',
   'tags' => ['tag', 'tag2'], //tags will be created if they don't exist
]);

//attaching tags
$newsItem->attachTag('tag3');
$newsItem->attachTags(['tag4', 'tag5']);

//syncing tags
$newsItem->syncTags(['tag1', 'tag2']); // all other tags on this model will be detached

//retrieving models that have any of the given tags
NewsItem::withAnyTags(['tag1', 'tag2'])->get();

//retrieve models that have all of the given tags
NewsItem::withAllTags(['tag1', 'tag2'])->get();

More info – in the article from the authors: An opinionated tagging package for Laravel apps

Similar package: rtconner/laravel-tagging


7. spatie/laravel-sluggable: Generate slugs when saving Eloquent models

URL: https://github.com/spatie/laravel-sluggable

This package automatically generates slugs from your title/name or whatever field you want. Here’s how you specify that in model:

use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasSlug;
    
    /**
     * Get the options for generating the slug.
     */
    public function getSlugOptions() : SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('name')
            ->saveSlugsTo('slug');
    }
}

And then magic happens:

$model = new Article();
$model->name = 'activerecord is awesome';
$model->save();

echo $model->slug; // outputs "activerecord-is-awesome"

You can also specify different slugs for different languages, also configure what happens on updating the record, what separator to use (“-” or “_”) and more parameters.

More info from the authors: A PHP 7 / Laravel package to create slugs

Similar package: cviebrock/eloquent-sluggable


8. spatie/eloquent-sortable: Sortable behaviour for Eloquent models

URL: https://github.com/spatie/eloquent-sortable

This package provides a trait that adds sortable behaviour to an Eloquent model.
Here’s how you specify the sortable field in the model:

use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

class Article extends Eloquent implements Sortable
{

    use SortableTrait;

    public $sortable = [
        'order_column_name' => 'order_column',
        'sort_when_creating' => true,
    ];
    
    ...
}

And then the column is filled in automatically:

$article = new Article();
$article->save(); // order_column for this record will be set to 1

$article = new Article();
$article->save(); // order_column for this record will be set to 2

$article = new Article();
$article->save(); // order_column for this record will be set to 3

//the trait also provides the ordered query scope
$orderedRecords = Article::ordered()->get(); 

9. dimsav/laravel-translatable: A Laravel package for multilingual models

URL: https://github.com/dimsav/laravel-translatable

We have a separate article for 10 Best Laravel packages for multi-language projects, and this one is the obvious leader on the market.

You need to create database migrations according to this schema:

Schema::create('countries', function(Blueprint $table)
{
    $table->increments('id');
    $table->string('code');
    $table->timestamps();
});

Schema::create('country_translations', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('country_id')->unsigned();
    $table->string('name');
    $table->string('locale')->index();

    $table->unique(['country_id','locale']);
    $table->foreign('country_id')->references('id')->on('countries')->onDelete('cascade');
});

Next step is to configure your main Model and also related model for translations:

// models/Country.php
class Country extends Eloquent {
    
    use \Dimsav\Translatable\Translatable;
    
    public $translatedAttributes = ['name'];
    protected $fillable = ['code'];    
}

// models/CountryTranslation.php
class CountryTranslation extends Eloquent {

    public $timestamps = false;
    protected $fillable = ['name'];

}

Then you can fill in and use translations, like this:

  $data = [
    'code' => 'gr',
    'en'  => ['name' => 'Greece'],
    'fr'  => ['name' => 'Grèce'],
  ];

  $greece = Country::create($data);
  
  echo $greece->translate('fr')->name; // Grèce

Similar package: spatie/laravel-translatable


10. spatie/laravel-medialibrary: Associate files with Eloquent models

I intentionally left this awesome package the last in the list, because I assume/hope everyone knows it. It has over 1 million downloads overall. But for those who don’t know it…

Here’s how you configure your models to have media.

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;

class News extends Model implements HasMedia
{
    use HasMediaTrait;
   ...
}

And then you can attach any media files to the model:

$newsItem = News::find(1);
$newsItem
   ->addMedia($pathToFile)
   ->toMediaCollection();

Finally, here’s how to retrieve those files:

$mediaItems = $newsItem->getMedia();

$publicUrl = $mediaItems[0]->getUrl();
$publicFullUrl = $mediaItems[0]->getFullUrl(); //url including domain

In the database, records are stored in a separate media table which uses Polymorphic Relations.


So, that’s it, TOP 10 hand-picked packages, along with their similar packages. Anything I’ve missed? Any more packages to enhance Eloquent?