Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
[Request] Model self-validating trait #3751
I saw on Twitter that for 4.2 the soft delete functionality would be implemented as a trait. As we now have the option of traits to enable selective use of Eloquent functionality, I'd like to request the reconsideration of self-validating models (see #1169 back before the release of 4.0).
I think self validating models will help clean up a lot of validation code from controllers and help ensure the validity of model data being saved in the database. I believe having it available as core functionality in Laravel will allow for more consistent use, much like model validation in Rails.
In essence, prior to saving a model (whether it is being created or updated), validation rules would be run over it and return either a boolean or raise an exception indicating that the save did not complete. Model rules could be available on a protected static variable, like
The model validation should also consider use of the
The following methods available on an Eloquent model would allow additional functionality on top of just ensuring invalid models aren't saved. Access boolean states of whether the model is valid or not, and access the errors/messages of when a model is invalid.
Yeah I think we can have some discusson on this. A few initial thoughts that come to mind, a simple
Would be interested to hear what people think on if this should be a part of the core or if we should let the community manage it through packages.
Another possibility is a simple set of rules, and then a callback that receives the validation object, for use with conditional validation rules. The basic set of rules would be applied to all states, and then you can conditionally add rules based on whatever logic you wish.
@taylorotwell I use Ardent and Magniloquent and would be willing to create a uniform interface and trait set that implements the key features from both. I would think that they need to be implemented in a way like your SoftDeletingTraits in that they should be opt-in only so as to not affect any previous code usage.
Having found both of these community packages either lacking features, unit tests, or otherwise abandoned, I'm actually trying to figure out the direction to take some of our own software going forward. Right now it seems the best thing to do is to fork Magniloquent and implement it as a set of traits in a way that's more compatible with Eloquent's model changes. Another alternative is to fork Illuminate\Database and implement it directly and then provide you the opportunity to review and revise to your liking.
It would be better all around for Laravel if it were in the core vs. a separate package which leads to fragmentation as fewer people use each package and therefore submit issues. Can you share whether or not you'd actually consider it as a core pull request (maybe share the interface you'd like to see implemented) before I get started on a 3rd-party package.
The only thing is where the rules themselves are saved. i.e. I dont want to store my validation rules inside my model. There are times I need to validate something (i.e. a form) but not always in the process of 'saving' to a model (such as an ajax request to check validation without actually saving it).
So the way I've extended Laravel is I have a Validator Service that is 'abstract'. It has a validate($rules) input. Then I just extend the validator service for each set of domain logic rules (i.e. UserValidator, PostValidator). In the extended class I just do something like this
And just define as many sets of rules as I like. Then all my Model does is on the "saving()" event, calls its own validator service, and validates against the rule provided.
But best of all - I can inject my UserValidator elsewhere - like on a form unrelated to saving to the model.
I'm working on a ardent esque model class that validates, however I've built in "scopes" for validation.
so the $rules array contains 'global', 'create', and 'update' rules. as implied the global and current scope rules are merged during validation, and just like ardent model->save() runs validation and returns true/false. then there is also the model->validates() function which does the same without save.
its not just validation, it adds custom messages per scope to the validation errors too, and allows you to define data types for the model (allowing array/object values to be automatically serialised on save and unserialise on access), and auto hashes password values via data type if set.
this basically creates setAttribute and get*Attribute functions through the __call method, so not nesassery, but would be really nice as a trait.
it currently "works" but isn't pretty and needs a bit more dev to be production ready.
maybe it would help with the dev of adding this to the core?
it was build with php5.3 in mind, but as this would be a laravel 4.2 thing, it may make more sense to implement as a trait as suggested above:
one thing to note with validation is the rules confirmed and unique.
unique is pretty easy as you can just modify the rules to include the id if exists (my model and ardent cover this pretty easy).
confirmed however adds attributes to the model, which unless removed before inserting to the db causes pro exceptions.
maybe globally eloquent should remove all **_confirmation attributes before save, regardless of if it uses the validation trait.