theriddleofenigma/laravel-model-validation
Declare validation rules directly on your Eloquent models and have them run automatically on the events you choose, such as saving, creating, or updating. Invalid saves throw Laravel's ValidationException, so no form requests or repeated validator calls are needed.
Architecture fit
The package implements validation as an Eloquent concern: a trait on the model that declares rules and hooks the model event lifecycle (saving/creating/updating) to run the Laravel validator before persistence. Architecturally this inverts the dominant Laravel convention, where validation sits at the boundary (Form Requests) or in explicit application services. The trade-off is real and defensible: it centralizes data invariants next to the schema they describe and guarantees they travel with the model regardless of entry point (HTTP, queue job, console command, Nova/Filament admin). The cost is that models become responsible for input semantics and, on failure, throw a ValidationException — an exception type with HTTP redirect/JSON-response semantics baked in. For a domain-heavy codebase this is a legitimate "always-valid entity" pattern; for a typical CRUD app it duplicates or conflicts with existing Form Request validation and creates two sources of truth. Expect to pick one, not both.
Integration feasibility
Mechanically trivial: composer require, add Enigma\ValidatorTrait, declare rules, opt into events. No service provider wiring or migrations implied. The real work is not installation but governance — establishing team-wide rules for when rules live on the model versus in a Form Request, and preventing drift. That is a documentation-and-review problem, not an engineering one.
Technical risk
Model::where(...)->update(), upsert, insert), saveQuietly(), or raw SQL. Validation is therefore advisory, not an invariant. Any teammate who assumes "the model validates" is one ->update() call away from corrupt data. Mitigation: this must be paired with database constraints for anything that actually matters.ValidationException thrown from a queue worker or artisan command does not have a request to redirect; behavior must be verified and handled explicitly.Key questions
firstOrCreate/updateOrCreate?sometimes, required_if), nested/array, and custom Rule objects supported, and are attribute-name/message customizations publishable?shouldValidate(), saveQuietly parity) and is it documented?Stack fit Best fit: greenfield or actively modernized Laravel 12/13 services with domain-rich models and multiple write paths (HTTP + jobs + admin panels) where boundary validation alone leaves gaps. Poor fit: Laravel 10/11 estates, teams standardized on Form Requests, or codebases where models are already thin and validation lives in actions/services. Given the dependency and maturity signals, treat this as a trial, not an adopt.
Migration path Do not retrofit existing models. Introduce incrementally:
ValidationException raised by the trait for two sprints and compare against Form Request failures to confirm no false positives.Compatibility
Verify framework/PHP constraints against the actual composer.json before anything else. Check interactions with any packages that write to models directly (admin panels, audit/logging packages, importers) — these fire model events and will now be subject to validation, which can break bulk operations unexpectedly. Confirm ValidationException handling in bootstrap/app.php (Laravel 11+ style) produces acceptable API responses.
Sequencing Contract test → single-model pilot → observability window → convention doc + architecture test (e.g., a static check that any model using the trait is on an approved list) → phased expansion. Budget a hard go/no-go checkpoint at the end of the pilot: if maintenance responsiveness or coverage gaps look unresolved, revert — the trait is one line to remove.
Maintenance You are taking a dependency on an unversioned-in-practice, single-maintainer package. Budget for the possibility of vendoring the trait (it is small and MIT-licensed) if the upstream project stalls; the exit cost is low, which is the strongest argument in its favor. Internal maintenance is the real load: someone must own the "where do rules live" convention and enforce it in review.
Support No commercial support, no dependents to lean on for community answers. Expect to read the source. This is acceptable for a 150-line trait and unacceptable for anything load-bearing across many models.
Scaling Runtime overhead is negligible — a validator run per save. The scaling problem is organizational: as model count grows, rule definitions on models become a second schema, and keeping them in sync with migrations becomes manual toil. At ~10+ instrumented models you will want either a generator or a return to explicit validation objects.
Failure modes
ValidationException surfacing in queue workers, seeders, and console commands, halting jobs or CI.Ramp-up Very low for individuals (an hour to read the README and trait). Moderate for a team, because the value depends entirely on a shared, enforced convention. Plan a short internal write-up, one worked example, and an architecture test before broad rollout. Overall recommendation: conditional trial, single-model pilot, hard revert checkpoint, database constraints retained as the actual guarantee.
How can I help you explore Laravel packages today?