Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Model Generator Laravel Package

krlove/eloquent-model-generator

Generates Eloquent model classes from existing database tables. It inspects your schema and creates models with proper fillable fields, table names, primary keys, and relationships, saving time when working with legacy databases or reverse-engineering an existing application.

Deep Wiki
Context7

Getting Started

Install as a dev-only dependency — this is a scaffolding tool, not runtime code:

composer require --dev krlove/eloquent-model-generator

Publish the config if you want to override defaults (namespace, base class, output path, template, backup behaviour):

php artisan vendor:publish --provider="Krlove\EloquentModelGenerator\Provider\GeneratorServiceProvider"

Point it at a table and generate a model:

php artisan model:generate --table-name=orders

That writes App\Orders (or a class derived from the table name) next to your existing models, containing the table name, $fillable/$guarded, $casts, timestamp handling, and — depending on config — inferred belongsTo/hasMany/hasOne relations.

Where to look first:

  1. config/model-generator.php — sets model_defaults.namespace, base_class_name, output_path, no_timestamps, date_format, connection, and backup.
  2. The command signature (php artisan model:generate --help) for per-invocation overrides: --class-name, --namespace, --output-path, --base-class-name, --connection, --no-backup, --template.
  3. The bundled template stub inside the package — this is the file your generated class is rendered from, and the first thing to fork if your team has conventions.

First real use case: you inherited a legacy MySQL database with 80 tables and no models. Generate them into a throwaway namespace first, inspect a couple for sanity, then move them into App\Models.

Implementation Patterns

Generate from a schema, not from migrations. The package introspects a live connection. The cleanest workflow is: dump the schema (mysqldump --no-data, pg_dump -s), import it into a scratch database, and generate against that with a dedicated connection:

php artisan model:generate --table-name=invoices --connection=legacy --namespace="App\\Models\\Legacy"

This keeps generation independent of your real dev database and makes the output reproducible in CI.

Loop over tables for bulk generation. There is no "generate everything" flag, so shell it:

for t in $(php artisan tinker --execute="echo implode(' ', array_column(DB::select('SHOW TABLES'), 'Tables_in_'.DB::getDatabaseName()));"); do
  php artisan model:generate --table-name="$t" --no-backup
done

Wrap this in a small custom Artisan command in your app so it's versioned and reviewable.

Customize the template once, then never touch generated output. Copy the package's model template into resources/templates/model.php (or wherever your config points), and add your house style: declare(strict_types=1);, final class, a @property docblock block, a protected $connection constant, or an implements clause. Every subsequent model:generate inherits it. This is the single highest-leverage customization in the package.

Treat generation as a one-time bootstrap, not a sync. Generated models are a starting point. Re-running the generator over a file you've since edited will clobber changes (the default backup writes *.php.bak, which is easy to lose track of). The pattern that holds up: generate once into a stubs/ or app/Models/Generated/ namespace, then hand-copy and refine. If you genuinely need regeneration, use --output-path to a scratch directory and diff.

Pair with laravel-ide-helper, don't replace it. krlove produces real classes; barryvdh/laravel-ide-helper produces @property annotations from the same schema. They overlap but don't conflict — generate classes here, then run php artisan ide-helper:models --nowrite to enrich them with accurate property docblocks. For a legacy DB, the combination gets you an editor that autocompletes $order->customer_name on day one.

Use relation inference as a review prompt. The generated belongsTo/hasMany methods are guesses based on foreign keys. They're right often enough to save typing and wrong often enough (polymorphic, composite keys, non-conventional names) to require review. Diff the generated file against what you'd write by hand; the deltas are a free map of your schema's oddities.

Generate fillable, then tighten it. The generator typically dumps every column into $fillable (or uses $guarded = []). Mass-assignment protection is a security boundary, so treat the generated list as a draft and remove anything that shouldn't be user-writable (is_admin, balance, deleted_at).

Gotchas and Tips

The package is archived (last release Nov 2023). Treat it as frozen. It will work fine on Laravel 9/10 with PHP 8.1/8.2, but do not expect Laravel 11/12 fixes, PHP 8.3+ support, or responses to issues. Fork it if you need to keep it alive, or budget for replacing it. Do not add it to a long-lived production dependency tree without an exit plan.

It overwrites files. By default it backs up to <Model>.php.bak, and --no-backup disables that. If you regenerate over a hand-edited model with --no-backup, the changes are gone. Always generate to a scratch --output-path when experimenting, and never run it blindly across a directory of real models.

Generation needs a live, reachable connection. --connection selects a configured Laravel connection, so the connection must be defined in config/database.php and reachable at CLI time. SQLite works for simple cases but introspection is weaker (limited FK metadata → weaker relation inference). On MySQL/Postgres you'll get the best relation detection.

Column type → cast mapping is conservative. Enums, spatial types, jsonb, custom Postgres types, and unsigned bigint FKs frequently land as string or are skipped. Review $casts and add AsEnumCollection, AsArrayObject, etc. by hand.

Timestamp and primary key detection assume conventions. Tables without created_at/updated_at need no_timestamps, and non-id primary keys or non-incrementing keys need manual correction ($primaryKey, $incrementing, $keyType). UUID/ULID PKs are not detected reliably on older versions.

Table name pluralization is conventional. For irregular names (person → people, prefixed tables like tbl_users), the inferred class name and $table property will be off. Always pass --class-name explicitly for irregular tables, and verify the generated protected $table line.

Namespace vs. output path are separate knobs. --namespace sets the PHP namespace written into the file; --output-path sets where the file goes. Setting one but not the other produces a file whose namespace declaration doesn't match its location — PSR-4 autoloading then silently fails. Set both together, or rely on model_defaults in config.

Backup noise pollutes git. If you leave backups enabled and regenerate often, you'll commit .php.bak files. Add *.php.bak to .gitignore, or prefer --no-backup combined with generating into a scratch path.

Don't generate pivot tables. Many-to-many join tables (role_user, post_tag) get their own models with no id. These are noise; skip them in your bulk loop by checking for exactly two FK columns and no primary key.

Debugging a weird output: the rendering is template-driven. If the generated file looks malformed or missing sections, open the template stub — the bug is almost always there (a column the template doesn't anticipate), not in the introspection layer. Adding {{ dump($columns) }}-style debugging into a copy of the template is faster than reading the source.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core