jeromegn/poutine — pull request #1 by jmreidy (2012-02-13 02:35:32+00:00)
Title: Add validations (code review)

Hey guys,

This isn't 100% done yet, but I wanted to open a pull request so that I can get your feedback on the API and implementation.

As of now, I've plugged validation functionality into Poutine's model class. There's a new `beforeSave` hook that's called each time a model instance is inserted, updated, or upserted. The hook is only firing for model instances right now (not POJOs), and doesn't apply to the `update_all` method (which is behavior similar to other ORMs). If there are any validators present, the beforeSave hook triggers them to run, and if any fail, saving the model is prevented.

Adding validators is extremely easy: just use `@validates "field", validatorFunction`. This signature follows the pattern of the existing `@field` definition. The validatorFunction receives four arguments: the model document, the name of the field being validated, the value of that field, and a callback; the `this` value is the model instance. Validation failures are marked by Errors which can be thrown or passed directly to the callback, which makes writing custom validators both easy and readable. You can define multiple validator functions in a single `@validates` statement. As each validator is run, errors are collected by field and passed back on a single Validation Error, which is simply an `Error` object with an `errors` attribute. The `errors` attribute is a hash of validated field names to arrays, with each array containing the collection of validation errors.

I'm at the point where I'm adding convenience validators; these will follow the model of `@validates "field", Validator.length.min(5)`. But before adding any more of these validators, I wanted to get your feedback on the actual validation implementation. There's tests for all this, so please look through those and feel free to message me with any questions and comments.

Thanks for all your work on Poutine, it's been a pleasure to go through the code in depth!