← all posts

Eloquent is an ORM, not a schema designer

·2 min read ·Laravel · Databases · Architecture

Eloquent is one of the best parts of Laravel. It is also the reason so many Laravel schemas are bad. When your only interface to the database is a model, you start designing tables by asking "what does the model need?"—and that question produces schemas that only make sense from inside PHP.

The database outlives the framework. I've worked on systems where the application code got rewritten and the tables stayed. The reverse almost never happens. That asymmetry tells you where the design effort belongs.

Tables first, models second

When I design a feature, I sketch tables before I touch artisan make:model. For the admissions system at the university, that meant thinking about applications, documents, and payments as data: which states an application can be in, which columns can never be null, what has to be unique, what happens to documents when an application is deleted.

None of those answers come from Eloquent. They come from the domain. Eloquent will happily store a null where the business says there must always be a value. The database won't—if you told it.

What the schema should carry

Constraints belong in the schema, not in model events:

$table->foreignId('application_id')->constrained()->cascadeOnDelete();
$table->string('status', 32)->index();
$table->unique(['application_id', 'document_type']);

Foreign keys, unique indexes, NOT NULL, column types chosen on purpose. Each one is a bug class that can no longer exist. A unique rule in a form request is a race condition; a unique index is a guarantee. If two parts of the app write the same table—a controller and a queued import, say—only the schema protects both paths.

Where Eloquent's job starts

Once the tables are right, Eloquent is exactly what it claims to be: a clean mapping layer. Relationships mirror foreign keys that actually exist. Casts mirror types that mean something. Scopes read well because the underlying data is well shaped.

The ORM is the last step of data modeling, not the first. Design the tables like the framework doesn't exist. Then let Eloquent make them pleasant to use.