Looking to hire Laravel developers? Try LaraJobs

laravel-schema-attributes maintained by liar88828

Description
PHP 8 attribute-driven schema compiler for Laravel. One schema class drives migrations, models, factories, controllers, and tests — no duplication.
Author
Last update
2026/03/20 14:15 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

Laravel Schema Attributes

Latest Version on Packagist PHP Version Laravel Version License

PHP 8 attribute-driven schema compiler for Laravel. One schema class drives everything — migrations, models, factories, controllers, and tests with no duplication.

Reverse Engineering Existing Migrations

Already have a Laravel project with migrations? Import them as schemas with one command:

# Scan all migrations → generate schema classes in app/Schema/
php artisan schema:scan

# Scan a specific table
php artisan schema:scan create_orders_table

# Generate migration-only schemas (no EloquentModel)
php artisan schema:scan --migration

# Generate full schemas with EloquentModel
php artisan schema:scan --model

# Print to console instead of writing files
php artisan schema:scan --print

# Overwrite existing schemas
php artisan schema:scan --force

Example — given this migration:

Schema::create('orders', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->string('status', 20)->default('pending')->index();
    $table->decimal('total', 10, 2);
    $table->timestamps();
    $table->softDeletes();
});

Generated OrderSchema.php:

#[EloquentModel(model: Order::class)]
#[Table(name: 'orders', timestamps: true, softDeletes: true)]
class OrderSchema
{
    #[PrimaryKey(type: 'bigIncrements')]
    public int $id;

    #[Column(type: 'unsignedBigInteger', index: true)]
    #[ForeignKey(references: 'id', on: 'users', onDelete: 'cascade')]
    // #[BelongsTo(related: UserSchema::class)]  ← set the related schema
    // #[Fillable]
    public int $user_id;

    #[Column(type: 'string', length: 20, default: 'pending', index: true)]
    // #[Fillable]
    public string $status;

    #[Column(type: 'decimal', precision: 10, scale: 2)]
    // #[Fillable]
    public float $total;
}

After scanning, review the generated schemas and uncomment/add #[Fillable], #[Required], #[Hidden], #[Cast] as needed.

Concept

#[EloquentModel(model: Article::class)]
#[Table(name: 'articles', timestamps: true, softDeletes: true)]
class ArticleSchema
{
    #[PrimaryKey(type: 'bigIncrements')]
    public int $id;

    #[Column(type: 'string', length: 191)]
    #[Fillable] #[Required] #[Min(2)] #[Max(191)]
    public string $title;

    #[Column(type: 'unsignedBigInteger')]
    #[ForeignKey(references: 'id', on: 'users', onDelete: 'cascade')]
    #[BelongsTo(related: UserSchema::class)]
    public int $user_id;
}

Then run one command to generate everything:

php artisan schema:refresh ArticleSchema

This generates:

  • ✅ Migration
  • ✅ Eloquent model with $fillable, $hidden, $casts, relations
  • ✅ Factory with correct Faker calls
  • ✅ PHPUnit test covering migration, model wiring, validation, persistence
  • ✅ API controller with validation, Auth injection, soft delete & restore

Installation

composer require liar88828/laravel-schema-attributes

Laravel auto-discovers the service provider. No manual registration needed.

Artisan Commands

Command Description
schema:make ArticleSchema Create a new schema class
schema:scan Reverse-engineer existing migrations → schema classes
schema:migrate ArticleSchema Generate migration
schema:model ArticleSchema Generate Eloquent model
schema:relations ArticleSchema Generate relation methods
schema:factory ArticleSchema Generate factory
schema:service ArticleSchema Generate Service layer class
schema:controller ArticleSchema Generate API controller
schema:test ArticleSchema Generate PHPUnit test
schema:refresh ArticleSchema Generate all of the above

Available Attributes

Migration

#[Table] #[Column] #[PrimaryKey] #[ForeignKey] #[ForeignSchema] #[HasOne] #[HasMany] #[BelongsTo] #[BelongsToMany]

Model

#[EloquentModel] #[Fillable] #[Hidden] #[Cast] #[Appended] #[UsesSchema]

Validation

#[Required] #[Email] #[Min] #[Max] #[In] #[Unique] #[Uuid] #[Confirmed] #[Regex] #[Numeric]

Auth Model Example

use Illuminate\Foundation\Auth\User;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;

#[EloquentModel(
    model:  UserModel::class,
    extend: User::class,
    traits: [Notifiable::class, TwoFactorAuthenticatable::class],
)]
#[Table(name: 'users', timestamps: true, softDeletes: true)]
class UserSchema
{
    #[Column(type: 'string', length: 191, unique: true)]
    #[Fillable] #[Required] #[Email] #[Unique(table: 'users', column: 'email')]
    public string $email;

    #[Column(type: 'string')]
    #[Fillable] #[Hidden] #[Cast('hashed')] #[Required] #[Confirmed]
    public string $password;

    #[Column(type: 'rememberToken')]
    #[Hidden]
    public ?string $remember_token = null;
}

HasSchema Trait

Adding use HasSchema to your model gives you:

// Schema-driven validation
User::schemaValidateOrFail($request->all());

// Update validation (ignores own unique fields)
$user->schemaValidateForUpdate($request->all(), ignoreUniqueFor: ['email' => $user->id]);

// Auto $fillable, $hidden, $casts, $table from schema
// UUID primary key auto-generation
// Relation resolution from schema annotations

Authors & Credits

This package was entirely created by AI.

Role AI
Code & Architecture Claude (Anthropic)
Helper & Consultation ChatGPT (OpenAI)
Human Supervisor liar88828

💡 This is an experiment in AI-driven open source development. Every line of code, architecture decision, bug fix, and this README was written by AI assistants guided by a human developer.

spatie/laravel-route-attributes is a lightweight package (~50KB) that only depends on illuminate/routing which Laravel already includes. If your project already has any Spatie package installed, there is zero additional cost.

License

MIT — see LICENSE.