Easily implement optimistic Eloquent model locking feature to your Laravel app.
composer require quarks/laravel-locking
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.
See LICENSE file.