Alternatives to Model-Based Validation?

Rails has an decent set of validation rules for its database models. You can specify that particular variables must be present or satisfy certain constraints, either by themselves (“must be two characters long”) or in relation to each other (“password can’t be blank for administrators”). I’ve written several of my own extensions to these for validating phone numbers, email addresses, tracking numbers, and the like.

It works fine, at first. But model-based validation breaks down in several situations. Here are a few examples:

1. Wizard-like interfaces break the rules. By definition, a wizard decomposes the process into several steps. Your model objects are often invalid until you finish the last step. I have yet to see a solution to this. Most people end up adding some sort of knowledge about the wizard to the model’s validation code (“If I’m only asking for the person’s name and address right now, don’t try to validate his email address”).

2. In Rails, you can’t save your models unless they satisfy all of the validity conditions. This problem probably won’t arise at first, but as your code base evolves, it can have some nasty side-effects. Like when a user can’t change his password, because the model has lately been changed to require a variable that used to be optional.

Seaside itself provides nothing to help you with validation. Search some archives and you’ll find people recommending Magritte, which is a metadata descriptor system for model objects. It was written by Lukas Renggli, who is one of the lead developers of Seaside itself.

Magritte improves the problematic situations above in a couple of significant ways. For one, Magritte descriptions can be configured on any object, not just on database models. In Seaside, a wizard is likely to be implemented with several components (one per page), so a corresponding model could be built with just the validation rules it needs. Additionally, Magritte is completely separate from your persistence layer, so you are free to save your model objects regardless of whether Magritte’s validation rules are satisfied.

But I’m still not satisfied with the approach. Model-based validation has a bad smell to me, though in some limited ways I am sure it is useful. But the more I look at systems that work this way, the more I see what looks like UI-specific code in the model. Should your model really be concerned whether the user has entered matching strings for “password” and “password confirmation”? What if I want to use real first-class objects to represent a phone number? Validation should happen before the data ever gets to the model. It strikes me that validation belongs in the form, not in the model. In Seaside, that means that validation would happen at the component level.

So I’m looking for a better way. How are others handling validation in Seaside? Beyond that, how do other frameworks help with form validation? The most intriguing thing I’ve seen so far is the “newforms” framework in Django, which couples form inputs to their validation.

It seems that this would be fairly easy to implement in Seaside. You could use blocks to make its behavior pluggable. If you end up using one particular form in several places, make your own subclass of Form and reuse it. Or if you only need it once, build the Form instance programmatically.

Are there any other frameworks that provide validation hooks but are not model-based?

Advertisements

5 Comments

Filed under Rails, Seaside

5 responses to “Alternatives to Model-Based Validation?

  1. Hi,

    Yes, there is. Here is a link to a paper describing the basic working principles of SUnit Based Validation,

    http://blogten.blogspot.com/2004/12/proper-abuse-of-sunit.html

    If you use VisualWorks, there is also a sample implementation of it in the bundle SUnit Extensions (which depends on SUnit Very Much, a backwards-compatible refactored implementation of SUnit).

    Thanks,
    Andres.

  2. Some comments:

    – Magritte normally does not do the validation within the model. During edit operations it works on proxy objects that are validated *before* the changes are applied to the model. Any validation problem does not affect the model.

    – The Magritte core framework is completely separate from any persistency solution, that is true. Hoever several people have written extensions to Magritte that allow one to make objects persistent according to their descriptions.

    – With “responsibility driven design” every object is responsible to hold correct data itself. Therefor it doesn’t make sense to me to put the validation somewhere else. What if you have 5 slightly different editors for the same object, do you really want to duplicate the validation everywhere?

    Cheers,
    Lukas

  3. beachcoder

    Also look at the Python library formencode (http://formencode.org) which provides a large set of validators (you can also write your own). Unlike Django newforms, it does not do form generation, but is also model-agnostic.

  4. Pingback: Top Posts « WordPress.com

  5. Pingback: Mold: Form Validation for Seaside « Something to Talk About

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s