Sometimes ActiveRecord is not enough to meet complicated validation needs. At TMXCredit we’ve created Themis - ActiveRecord extension which helps to organize validations in a better way and adds some flexibility. Here I’m gonna describe some problems which Themis solves after that I’ll take a brief look at possible alternative solutions.
Themis allows you to extract duplicated validations into module for reuse. Usually rails applications are small enough so you don’t need it. But sometimes you do.
The next example is pretty flat(in real life you probably would use STI or composition to
Patient models) but it illustrates where Themis could be useful.
Let’s say you have 2 models:
1 2 3 4 5 6 7 8 9
You see that both models have the same validation for
Themis allows you to fix the duplication problem by extracting common validations into a module:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
So now we keep the common validation in one place. If you want, you can include validation modules into each other to combine necessary validation.
Here is another problem which Themis solves.
We have the following models:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
So we have a model graph like this with
User model on the top:
It’s pretty small, but in real life the graph can be much deeper.
What would you do if you needed to apply different validations depending on context?
For example according to your business requirements users must be allowed to use
your application only in case if they’ve filled in all of the fields.
So you need to validate presense of
Person model and
It’s not a problem, just add the validations to appropriate models:
1 2 3 4 5 6 7
There is some percent of users who don’t finish registration process. But your marketing department wants to have an ability to contact them if they have entered an email address.
So that’s where the issue is: you can’t save records using validation rules written above.
With Themis you can declare number of validation strategies, and depending on context, chose which one you need.
Here is how a complete solution looks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
And here is how you would use it somewhere in a controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
If you think Themis is overkill for your project, you still have some options.
Using ActiveSupport::Concern for modularity
ActiveSupport::Concern is another way which allows to extract common validations
into module. Here how would
PersonValidation module described above could look:
1 2 3 4 5 6 7
Using conditional validation
If your requirements aren’t so fancy, you can be satisfied with a simple conditional validation, e. g.
1 2 3 4 5 6 7 8 9 10 11 12
To DRY up
:if options it’s good to use
1 2 3 4 5 6
:if => :use_full_validation will be additonaly passed to every method call
person inside the block.
The guys from the ROM project have their own validator called Vanguard(previous name is Aqeuitas). The sweet thing about it is that it allows to seperate validations and models according to DataMapper approach. The downside is if you use ActiveRecord you’ll have a zoo of validation tools. Also it may be still raw and I’m not sure is it possible to apply it to solve the described problem, but I’d encourage you to take a look at it.
ActiveRecord is good for plain and straightforward projects. In big enterprise applications usually we need more flexibility to meet different exotic requiments. We’ve created Themis to extend ActiveRecord and solve some of the problems. Actually I hope that ROM will be ready soon and we’ll have an ability to select right ORM before diving into development.
Thanks for reading. Hope the article was useful for you and I’m wating for your feedback!