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

Tomato Model Generator Laravel Package

tomatophp/tomato-model-generator

Tomato Model Generator scaffolds Laravel Eloquent models, generating fillable fields, relationships, and migrations to speed up CRUD setup in the Tomato PHP admin panel and keep model code consistent across your Filament resources.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal steps. Install as a dev-time tool, not a runtime dependency:

composer require --dev tomatophp/tomato-model-generator

Auto-discovery should register the service provider. Immediately verify what you actually got, because there is no published command reference:

php artisan list | grep -i tomato

Also read src/Console and src/Generators in vendor/tomatophp/tomato-model-generator before running anything. The real API surface lives there, not in the README — command signatures, prompt order, and which relationship types are actually supported are all discoverable in about ten minutes of reading source. Do that first rather than guessing at flags.

Pin and publish before you generate. Check constraints in composer.json (PHP, Laravel, and any Filament major) to avoid a version-mismatch install failure, then pin the dependency and publish anything publishable so defaults cannot shift under you on upgrade:

composer require --dev "tomatophp/tomato-model-generator:^1.0"
php artisan vendor:publish --provider="TomatoPHP\\ModelGenerator\\ModelGeneratorServiceProvider"

Commit whatever lands in config/ and stubs/. If nothing publishes, note that and treat the package's built-in stubs as immutable — it means you have no convention lever.

First use case. Pick one low-risk, genuinely CRUD-shaped entity from your backlog — something like Project or Ticket with a couple of foreign keys — and generate it into a scratch namespace rather than App\Models:

App\Models\Generated

Generate, read every line of the output, then diff it against what you would have hand-written. That comparison — not the feature list — is the evaluation. If you have no scratch-namespace option, generate first on a throwaway branch and delete it afterward.

Where to look first when something is wrong, in order: the command class in src/Console, the generator/stub it calls in src/Generators, then the published stub file. Nearly every surprise ("why is $casts empty?", "why did it skip my pivot?") resolves at one of those three layers.

Implementation Patterns

Single-entity bootstrap, then hand-own it. The most defensible workflow: run the generator once for a new entity, treat the output as a starting commit, and never run it again against that name. Generators are excellent at the first 80% and hostile to the last 20%, and the last 20% is where your accessors, scopes, and domain methods live. Write this rule down — "generator output is a one-time bootstrap" — before the second developer discovers regeneration.

Use it as a prompt-driven schema sketch. The interactive field/type/nullable prompts are the real value for a schema that is still moving. The productive loop on a young domain is: prompt through the entity, let it emit model plus migration, run the migration in a local DB, look at the table, then decide what's wrong with the shape. It compresses "what should this table look like?" from a design meeting into two minutes of CLI. Once the shape settles, stop generating and hand-edit.

Review the migration as the artifact, not the model. The migration is the part you must read closely — column types, nullability, index and foreign-key behavior, and down() correctness. If the generator gets a decimal precision or an unsigned foreign key subtly wrong, the migration is where it shows up. The model's $fillable and $casts are cheap to correct; a bad migration on a shared database is not.

Pair with the rest of the factory/seed pipeline. The generator gives you model + migration; wire the rest yourself with native commands rather than expecting the package to cover it:

php artisan make:factory ProjectFactory --model=Project
php artisan make:seeder ProjectSeeder

Then add the inverse relations by hand. If the generator emitted hasMany on the parent, confirm the child's belongsTo exists — generated relationship pairs are frequently one-sided.

Generate in dependency order. Parents before children means foreign-key classes exist when the child's migration runs, and it makes it easier to spot where the generator inferred a foreign key from a naming convention versus where it guessed wrong.

Feed it into your Filament/TomatoPHP admin layer. This package's leverage is entirely inside that ecosystem — generate the model layer, then let your Filament resource generators consume it. If you are not on that stack, native make:model -mfsc does the same job with zero discovery cost, and you should use that instead.

Standardize stubs if you can publish them. If stubs are publishable and overridable, that is the one extension point worth investing in: bake in your namespace, declare(strict_types=1), trait usage (HasFactory, your audit trait), and base-model extension once, and every future entity inherits the convention. If stubs are not publishable, downgrade your expectations accordingly — you have a code emitter, not a convention-enforcement tool.

Gotchas and Tips

Namespace collisions are the top risk. Generating into App\Models can silently overwrite or conflict with an existing model that carries hand-written casts, accessors, scopes, or traits. Generate into App\Models\Generated on your first several runs and only "promote" files you have read. Set an alias rule or a policy before generating entity number two.

Regeneration is not idempotent in any way that matters. Assume a second run clobbers edits. If you need to change the schema after generation, hand-write the migration — that is normal Laravel work, not a failure of the tool.

Relationship inference is best-effort, and the failure mode is silence. Composite and non-standard primary keys, polymorphic relations, custom column types, and unconventional naming will be mis-handled or quietly skipped rather than erroring. After generating a relational entity, explicitly check: is the foreign key column type correct, is the constraint there, is the inverse relation defined, is the relation method name what you'd expect.

$fillable and $casts are a starting point, not a security review. Generated fillable arrays tend toward "all columns." For anything user-writable, audit it — a generated fillable list containing is_admin or user_id is a mass-assignment bug you shipped because it looked complete.

Config drift on upgrade. Unpublished config or unpinned versions can change generated output between patch releases with no warning. The v1.0.1 changelog is a bare compare link, so if you upgrade, diff src/ yourself:

git diff v1.0.0..v1.0.1 -- vendor/tomatophp/tomato-model-generator/src

Pin ^1.0 and treat patch bumps as potentially behavior-changing. At 1.0.x with undocumented releases and a 2024-03-28 last release, semver tells you less than you'd like. Read the diff or don't upgrade.

Check for a dry-run or target-directory option early. Without one, every generate is a file write, which means you can't use this as a CI drift check and you can't preview before touching disk. If dry-run exists, use it habitually; if not, always generate on a clean branch so git status is your preview.

Test against an awkward schema, not a happy path. One spike entity with a foreign key, a non-standard key, a json or enum column, and a nullable field will surface more than ten clean entities will. That is the run that tells you whether to standardize.

Know the exit path and say it out loud. Output is plain Laravel code — you keep the files whether or not you keep the package. Drop the dev dependency and nothing breaks. That bounds the risk to engineering time, which is the argument that gets a spike approved.

Debugging order. Command not found → service provider not discovered (check composer.json extra.laravel.providers, or the Filament major mismatch). Command runs but output is wrong → the stub, not the command. Migration fails → read the generated migration before touching the generator.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core