quarks/laravel-locking

Easily implement optimistic Eloquent model locking feature to your Laravel app.

1.0.1 2022-07-17 17:04 UTC

This package is auto-updated.

Last update: 2024-04-17 21:05:28 UTC


README

Easily implement optimistic Eloquent model locking feature to your Laravel app.

Latest Version Downloads PHP Version License

Installation

composer require quarks/laravel-locking

Usage

In your migration classes, add the version column to your table as below:

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::table('blog_posts', function (Blueprint $table) {
        // create column for version tracking
        $table->lockVersion();
        // or to use a custom column name e.g., lock_version
        $table->lockVersion('lock_version');
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('blog_posts', function (Blueprint $table) {
        $table->dropLockVersion(); // or $table->dropLockVersion('lock_version');
    });
}

Then add the LocksVersion trait your model classes as follows:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Quarks\Laravel\Locking\LocksVersion;

class BlogPost extends Model
{
    use LocksVersion;
    
    /**
     * Override the default lock version column name, optional.
     */
    protected static function lockVersionColumnName()
    {
        return 'lock_version';
    }
}

In your blade templates, include the current lock version as part of the form using the lockInput directive as below:

<form method="post">
    @lockInput($blogPost)
    
    <!-- more fields -->
</form>

In your controllers, fill the lock version from request using below helper:

namespace App\Http\Controllers;

use Quarks\Laravel\Locking\LockedVersionMismatchException;

// ... other imports

class BlogPostController extends Controller
{

    // ... more methods

    public function update(BlogPost $blogPost, BlogPostRequest $request)
    {
        $data = $request->validated();
        $blogPost->fill($data);
        $blogPost->fillLockVersion();

        try {
            $blogPost->save();
        } catch (LockedVersionMismatchException $e) {
            abort(409, 'This model was already modified elsewhere.');
        }
    }
}

Your model update can now be simply protected from concurrent updates as shown above.

License

See LICENSE file.