Tuesday, August 09, 2011

Rails 3 Custom Validator Quandary

I'm trying to figure out the "best" way to support discovery of custom validator errors on a Rails 3 model.

My model has both standard and custom validators. I need to check for validation errors from the custom validators, in both controller and template.

My slap-dash solution was to add an additional error message keyed to the field name suffixed with a validator-specific extension. For example, the standard message would be added to errors[:foo], and a custom message to errors[:foo__bar].

This works, but I really don't like it much--hence my plea for ideas. Here's the options I've considered so far, in no particular order.

(1) Add a model function that hides the logic. Easy, but vaguely discomforting.

(2) Check for the validator in the model's "initialize" method and if it's there, add an instance method. Similar to (1), but still far-removed from the validator.

(3) Expose something in the validator. Add it to the model class via an include, or dynamically in the model initializer.

(4) Have the validator add a method (foo_xxx? or something similar) to the instance at validation time. Only models that have been validated would have those methods, which gives me the heebie-jeebies.

(5) Pass in the class (instance?) in the EachValidator's options hash, and have the validator tweak the class (instance?) at init time. Having to pass in the class I'm already in seems janky, but...?

Updated:


(6) The "validates_with" also looks for a "setup" method in the validator (not an ActiveModel::EachValidator, but an ActiveModel::Validator) and passes "self" to it. "Sexy" validations use "validates_with" underneath, so this may be another approach.

The nature of my question, and my list of possible solutions, makes me wonder if I'm thinking about this the wrong way, and/or missing something *completely* obvious--am I?

No comments: