A powerful Laravel package to handle ownership relationships between Eloquent models with zero configuration on models, automatic API responses, and dynamic registration.
Everything you need to manage ownership relationships in your Laravel application
No traits or interfaces required. Works with any Eloquent model out of the box.
Automatically inject ownership information into your JSON responses via middleware
Keep track of ownership changes over time with historical records
Register ownable models through config or dedicated API endpoints at runtime
Simple @owns directive for quick ownership checks in your Blade views
Ready-to-use endpoints for managing ownership and registrations
Make sure your environment meets these requirements
PHP ^8.3 or higher
Laravel ^12.0
Get started with Laravel Ownable in just a few steps
Add the package to your Laravel project using Composer:
composer require sowailem/ownable
Execute the migration to create the database tables:
php artisan migrate
Learn how to manage ownership without modifying your models
The Owner facade is your primary tool for managing ownership relationships. No traits or interfaces required on your models!
Assign ownership of any model to another. This automatically handles marking previous ownerships for that entity as inactive.
use Sowailem\Ownable\Facades\Owner;
// A User owning a Post
Owner::give($user, $post);
// A Team owning a Project
Owner::give($team, $project);
Quickly verify if a specific owner currently owns an entity:
use Sowailem\Ownable\Facades\Owner;
if (Owner::check($user, $post)) {
// Authorized
}
Transfer ownership from one entity to another:
use Sowailem\Ownable\Facades\Owner;
Owner::transfer($oldOwner, $newOwner, $post);
Get the actual model instance of the current owner:
$owner = Owner::currentOwner($post); // Returns User, Team, etc.
This is the most powerful feature of the package. The AttachOwnershipMiddleware is automatically registered globally. It recursively scans your JSON responses and injects ownership data for any model registered as "ownable".
JsonResponse.config/ownable.php or via the dynamic API.Add models to your configuration:
'ownable_models' => [
\App\Models\Post::class,
\App\Models\Comment::class,
],
Original Response
{
"id": 1,
"title": "Hello World"
}
Enhanced Response (Automatic)
{
"id": 1,
"title": "Hello World",
"ownership": {
"id": 45,
"owner_id": 1,
"owner_type": "User",
"ownable_id": 1,
"ownable_type": "Post",
"is_current": true,
"owner": {
"id": 1,
"name": "John Doe"
}
}
}
Change the injection key in config/ownable.php:
'automatic_attachment' => [
'enabled' => true,
'key' => 'meta_ownership',
],
Check ownership directly in your views with the @owns directive:
@owns($user, $post)
<button>Edit Post</button>
@else
<span>Read Only</span>
@endowns
Complete reference for all available methods and classes
Static methods available via the Owner facade:
Give ownership of an ownable entity to an owner.
Check if an owner owns a specific ownable entity.
Transfer ownership of an ownable entity from one owner to another.
Get the current owner of an ownable entity.
The package provides built-in endpoints for managing ownership and registrations. These are prefixed with /api/ownable by default.
Give ownership of an ownable entity to an owner.
Transfer ownership from one owner to another.
Check if an owner owns a specific entity.
Remove ownership of an entity.
Get the current owner of an entity.
List and filter ownership history records.
Register a new model class for automatic ownership attachment dynamically.
Real-world scenarios and use cases
You might have Users owning Projects, and Projects owning Tasks. This is fully supported out of the box.
// User owns Project
Owner::give($user, $project);
// Project owns Task
Owner::give($project, $task);
// Verify hierarchy
if (Owner::check($project, $task)) {
// Project is the owner of this task
}
Protect your routes easily using the Owner facade in your middleware or controllers.
public function update(Request $request, Post $post)
{
if (!Owner::check($request->user(), $post)) {
abort(403, 'You do not own this resource.');
}
$post->update($request->all());
}
Register new models as ownable via the API without modifying your code. Perfect for CMS or highly dynamic applications.
// Request to register a new model class
POST /api/ownable/ownable-models
{
"name": "Document",
"model_class": "App\\Models\\Document",
"description": "Client documents"
}