More On CF+Hibernate - Do We Need A CFValidate Tag?

Posted By : todd sharp Posted At : June 23, 2008 12:51 PM Posted In: ColdFusion

9

To expand a bit on my last post I wanted to brainstorm on some more potential enhancements for CF 9's potential Hibernate integration. Specifically I'd like to propose the ability to define validations within an object. I know some folks cringe when it comes to this topic, but check out my pseudo code below. I think what I propose could really work, and greatly simplify validation while still being powerful (with potential custom validations).

<cfcomponent displayname="User Component" extends="UserBase" output="false">
    
    <cfproperty name="userID" accessor="true" hint="User ID" dbtype="char" length="35" primaryKey="true" />
    
    <cfproperty name="first" accessor="true" hint="First Name" dbtype="varchar" length="50">
        <!--- required: --->
        <cfvalidate type="required" message="You must enter a first name." />
        <!--- maxlength (could derive length) --->
        <cfvalidate type="maxlength" maxlength="50" message="First name is limited to 50 chars" />
        <!--- what about custom validation: --->
        <cfvalidate type="Users.CustomFirstName" message="Whatever..." />
    </cfproperty>
    
</cfcomponent>

To call the validation you'd simply do this:

<cfset user = createObject("component", "user") />
<cfset userErrors = user.validate() />

The call to validate would run all validations defined in your <cfvalidate> tags. If any of the specified validation routines failed then validate() would return an array of error structs which could each contain the message,error type, field name, etc. Custom validation is an intriguing prospect, allowing you to more granular control over the validation (instead of relying on the underlying CF validation methods like isEmail() for example). If there were complex objects within the bean (like an array of emailAddress objects as in my previous post) then validate() could potentially recurse over any <cfvalidate> tags defined in those objects as necessary.

I've also proposed a few additions to the cfproperty tag to allow more control over the db data type and the length and the ability to declare primary (and foreign?) keys.

Thoughts/Ideas/Suggestions?

Comments (9)

Sam Farmer's Gravatar I like this idea and direction a lot.

joshua cyr's Gravatar While it may not be perfect for all cases, it would seem that doing something like this would suit the goal for CF to be making our lives easier and increase our productivity. Not that validation is hard, but certainly it helps speed things up for general use.

What would also be interesting is to see how this could be used with a client site tie in for client validation (using spry for example). Not a requirement certainly, but an option.

<cfform type="text" cfvalidation="user.first">

Peter Bell's Gravatar Funnily enough, this is broadly how LightBase works. Every object has properties which have a custom data type and can be assigned validation rules.

As you try to get smarter, it gets more difficult as often the validation for a property is either dependent on the values of other properties or dependent on the state of the object (for a User to be an administrator, they need a valid email and password, but to sign up for a newsletter they only need a valid email).

it's definitely interesting territory though in terms of making hard things easy. The next question is whether you go the exstra mile and create a Django/Rails style full stack framework right in the language or whether you leave that to the community.

Adam Haskell's Gravatar I like the idea a good deal; very close to how my favorite Java framework works (without the generic getters and setters). Essentially you can add validation annotations to any action bean parameter (your present idea would just apply the concept across all objects). For a more rounded explaination of validation handlers check out http://stripesframework.org/display/stripes/Valida...

Jaime Metcher's Gravatar Hibernate Validator and OVal work something like this as well.

You can also annotate a function as having to return true or false, which allows you to create complex validation rules.

One of the more powerful ways to use this is to create a command object and then validate that. So SaveUserCommand would have a property "user", which would have to validate, plus some functions asserting various business rules which would have to return true. This allows you to have context-specific command objects with different business rules, or to re-use a basic domain model in different apps (one app might require a valid email address and another might not).

radekg's Gravatar Good idea. I like it. Going further there could be some new attributes for cffunction such as:
- postcondition
- precondition
Sample postcondition for for returntype="numeric" may be:

postcondition="result gte 1"

where result is some special keyword in scope of this attribute. postcondition attribute would check values returned from function at runtime so anytime this method is called programmer may be sure the value is what expected. Another reason to have this attribute is documentation purposes. With postcondition and precondition attributes doc tools could easily say:
this function returns numeric, at least 1 and expects arg of type string (for example) not longer than 3 chars.

radekg's Gravatar Well... actually precondition attribute should be for cfargument not cffunction.

todd sharp's Gravatar @Josh: There are tons of Ajaxish implications to what they're doing here. It will be interesting to see the side effects of what they're doing as it relates to Ajax.

@Peter: Yeah, there are obviously difficulties as your requirements become more complex (which is why I prefer brainstorming to engineering!! -- HA!). State specific validations are a huge one. You also bring up good points about where to draw the line with the language vs. community.... In my opinion the whole Hibernate integration is crossing the line a bit, but when you think about it - and I'm not trying to sound rude towards Adobe here but - much - hell - most -- of CF is bits and pieces of other languages/projects/frameworks. Verity, Flash Forms, Ajax stuff - the list goes on and on. So CFML makes all of those things easy to implement - so *where* do you draw the line (hypothetical question)?

@Adam -- Those validation handlers look cool...kinda reminds me of Flex validators now that I think of it. Can anyone speak to Flex validators?

@radekg - Sounds interesting - could you put together some pseudo code for how that would work? My brain works more visually - so to see a sample implementation would really help me understand more...

radekg's Gravatar @todd: I have posted some sample with descriptions here:
http://riait.co.uk/2008/06/25/pre-and-postconditio...