laracademy/generators
Laracademy Generators adds Artisan commands to scaffold Laravel models, controllers, migrations, and related classes. It reduces repetitive boilerplate with interactive prompts and customizable stubs, helping you create consistent files faster while following Laravel conventions.
Install the package into the Laravel app that owns the database you want to reverse-engineer:
composer require laracademy/generators
On Laravel 5.5+ the service provider is auto-discovered; on older versions add Laracademy\Generators\GeneratorsServiceProvider::class to config/app.php. Then confirm what you actually have installed before writing any workflow around it:
php artisan list | grep generate
php artisan help generate:model
Where to look first, in this order:
vendor/laracademy/generators/src/Console/ — the command classes are small and readable; the option list in each $signature is the real documentation.vendor/laracademy/generators/config/generators.php (publish with php artisan vendor:publish --provider="Laracademy\Generators\GeneratorsServiceProvider") — namespaces, output paths, and stub locations live here.vendor/laracademy/generators/src/Stubs/ — the templates that decide what your generated model/controller/views look like.First use case: point it at one legacy table and read the output before generating anything else.
php artisan generate:model legacy_customers
Open the generated file. If the $table, $fillable, $timestamps, and column list match reality, the package is behaving and you can safely scale to generate:models across the schema. If the model lands in the wrong namespace or the fillable list is wrong, fix the config/stub now — every subsequent generation inherits the same mistake.
This is a DB-first, one-shot generator. It is not a live sync tool: you generate once, commit the output, and then hand-maintain it like any other code.
Legacy database onboarding (the primary use case). Dump/restore the old schema into a local database, point a connection at it, then generate models table-by-table for the tables you actually care about rather than blasting all of them:
php artisan generate:model orders --connection=legacy
php artisan generate:model order_items --connection=legacy
Commit each model as a separate commit so the diff is reviewable. Follow immediately with a hand-written pass adding belongsTo/hasMany, $casts, and accessors — the generator will not infer relationships.
Snapshotting the schema as migrations. In parallel with the models, generate migrations from the same tables so the new app can rebuild the schema from scratch:
php artisan generate:migration legacy_customers
Treat the generated migration as a starting draft: reorder tables for foreign-key dependencies, replace implicit indexes with explicit $table->index()/foreign() calls, and verify column types against the source DDL.
Full scaffold for internal/admin CRUD. For back-office tables you need to manage quickly, generate the whole stack and strip it back:
php artisan generate:scaffold legacy_customers
The value here is the boilerplate you'd otherwise type (controller with index/show/store/update/destroy, Blade views, route entries). The pattern that works is: scaffold → immediately delete anything you don't want → add authorization ($this->authorize() / policies) → add validation rules derived from the real column constraints. Never ship a raw scaffold to a route reachable by untrusted users.
Multi-connection shops. Keep the legacy connection declared in config/database.php permanently and always pass --connection=; relying on the default connection means a stray .env change silently generates models from the wrong schema.
Team workflow. Generators are a local/onboarding tool. Document the exact commands and the required seed/schema state in the repo (a docs/legacy-import.md), pin the package version in composer.json, and commit the generated artifacts — not the process. Nobody should be running generators in CI or on a shared environment.
Customization via stubs. If your team has house style (strict types, final classes, typed properties, a base model, docblocks), copy the stubs into resources/stubs/generators/ or stubs/, point the config at them, and you get consistency for free on every future generation.
php artisan db:show / SHOW TABLES first.--force flag exists. Regenerating over a model you've since hand-edited will silently destroy relationships, casts, and scopes. git status before and after is cheap insurance; only regenerate into a clean tree.App\ with models in app/. Modern Laravel uses App\Models\ with models in app/Models/. Publish the config and fix namespaces/paths once, or you'll be git mv-ing files and fixing use statements across the whole app.$fillable is often "every column". That is convenient and also a mass-assignment hazard. Narrow it deliberately; consider $guarded plus explicit Form Requests instead.SHOW CREATE TABLE.$timestamps detection is heuristic. Tables with created_at/updated_at are fine; tables with differently named audit columns or deleted_at for soft deletes will need manual use SoftDeletes; and possibly public $timestamps = false;.routes/web.php. It appends routes directly to the routes file. On newer Laravel this may be routes/web.php vs an API routes file, and repeated scaffolding can duplicate entries. Review the routes diff every time.doctrine/dbal or raw driver queries; DBAL major-version constraints have historically broken against newer Laravel/DB versions. If generation throws on column metadata, suspect that before suspecting your database. Last release was October 2023, so test on your Laravel version early rather than mid-sprint.jsonb, enum types, and SQLite's loose typing may come through as generic strings — verify per driver.-vvv, and if output is surprising, open the command's handle() in vendor/ and read the exact query it issues. These commands are short; five minutes of reading beats guessing at flags.vendor/, and it survives composer update.How can I help you explore Laravel packages today?