wendelladriel/laravel-lift
Experimental Laravel package that supercharges Eloquent models with typed public properties matching your schema, powered by PHP 8 attributes. Add validation rules and other metadata directly on models and access them via handy methods, using Eloquent events for easy drop-in use.
Install the package via Composer:
composer require wendelladriel/laravel-lift
Start with a basic Eloquent model — add #[Property] attributes to declare public properties that mirror your database columns. For example:
use WendellAdriel\Lift\Attributes\Property;
#[Property]
class User extends Model
{
// No manual $fillable, $casts, or property declarations needed!
}
Lift will auto-generate public properties (e.g., public string $name), infer types from column definitions, and handle casts automatically — all visible to your IDE.
First use case: rapid model scaffolding with validation & rules embedded
use WendellAdriel\Lift\Attributes\Property;
use WendellAdriel\Lift\Attributes\CreateRules;
use WendellAdriel\Lift\Attributes\UpdateRules;
#[Property]
#[CreateRules(['email' => 'required|email|unique:users,email'])]
#[UpdateRules(['email' => 'required|email|unique:users,email,' . $this->id])]
class User extends Model {}
Rules appear inline, IDE shows them on model usage, and you avoid separate form request boilerplate.
Model-first development with IDE support
#[Property] and let Lift generate typed, discoverable properties.$user->name) without IDE warnings.Inline validation alongside model logic
#[CreateRules], #[UpdateRules], #[Rules] (for generic rules).#[Cast] for custom casters (including enums):
#[Property]
#[Cast(\App\Casts\StatusCast::class)]
#[Cast(enum: Status::class)] // enum support since v0.15
public Status $status;
Relationships via attributes
#[BelongsTo], #[HasMany], etc., including custom class names and key names:
#[BelongsTo(User::class, 'author_id', 'id')]
public User $author;
Event listeners embedded in models
#[Listener('created')], #[Listener('deleted')] to hook into Eloquent events without separate observers.Lift migrations for schema-first work
php artisan lift:migration to scaffold a migration based on existing model attributes (#[Property], #[Cast], #[Index]), reducing manual migration churn.⚠️ Experimental — expect breaking changes
^0.18), and track releases.Eloquent events must be enabled
saving, saved, etc.). If Event::dispatch() is disabled (e.g., via static::dispatchEvents() override), some features (like watch/immutable behavior) may not work.Name collisions & manual overrides
#[IgnoreProperty] to prevent Lift from overwriting it:
#[IgnoreProperty]
public string $full_name = '';
Stale property state after refresh
refresh() may leave stale public properties if not handled. Prefer $model->fresh() to reload fresh model instance.Enum casting requires explicit declaration
#[Cast(enum: MyEnum::class)] is not inferred automatically — specify it manually. Works only for string-backed enums.Custom column names in #[Property]
#[Property(columnName: 'db_field')] when PHP property name ≠ DB column. IDE auto-completion works only if column is explicitly mapped.IDE support requires proper setup
ide.json) or use the included #[Property] pattern — VS Code + Intelephense or PhpStorm work best.Immutable & Watched Properties
#[Immutable] prevents writes after model creation — great for domain objects. But: immutable only applies to lift-generated properties — custom properties remain mutable.Casting nulls safely
#[Rules(['nullable'])].Upgrade path
How can I help you explore Laravel packages today?