Nov 4 2005

Arf! Video: Automagic Validation

Posted by Joe Rinehart at 8:21 AM
20 comments
- Categories: Arf!

Today on Arf! TV, we'll look at how Arf! makes validation a breeze. Arf will automatically validate all properties for null, length, and type (making sure a date is a date, an int is an int, and so forth). What's really cool is that you can 1) override the validate() method to add your own validation rules, and 2) use XML-based "ui dictionaries" to control the text messages returned by validation, as well as localize other parts of your application.

Here's the video:

http://clearsoftware.net/demos/arfvideothree/

Comments

R. Symonds

R. Symonds wrote on 11/04/05 9:10 AM

Keep up the great work!
SOSensible

SOSensible wrote on 11/04/05 11:19 AM

Hey... great direction. I would think you would want to have the original dictionary(less) error available at all times also. Could you include that as an additional method to retrieve the "raw" exception type?
Sam Clement

Sam Clement wrote on 11/04/05 12:41 PM

Is the dictionary directory uploaded to the svn respository? I can't see it there...
ed chowdhury

ed chowdhury wrote on 11/04/05 1:27 PM

Very cool direction you're going in Joel. I had a couple of quick questions.

1) How would one go about adding custom validation methods for say email, or valid SSN, credit card number etc to a specific type of record?
2) What about more business logic type validation rules such as birthday must be greater than 20 years before today's date that don't specifically? Are there "hook" methods that we can overload to do pre and post processing?

ed
ed chowdhury

ed chowdhury wrote on 11/04/05 1:29 PM

Ooops, darn that itchy trigger finger. The post above should read..

2) What about more business logic type validation rules such as birthday must be greater than 20 years before today's date that aren't specifically defined by the table schema? Are there "hook" methods that we can overload to do pre and post processing?
Scott Stroz

Scott Stroz wrote on 11/05/05 8:10 AM

Joe - Any way to get Arf! validation adhere to check constraints in the DB?

That would be sweet.
SOSensible

SOSensible wrote on 11/05/05 9:01 AM

Scott,

I don't get your request. If the constraints are already in the database... wouldn't you get an error if they are violated? (Or is that what you are requesting... getting a certain error.) It seems you would not have universal support for something like this from ARF... this would be database vendor (dictionary) solution based. Not sure, but that is what it seems like you are asking for in this request.
Sam Clement

Sam Clement wrote on 11/05/05 1:53 PM

Just got it all working... very cool stuff!
Scott Stroz

Scott Stroz wrote on 11/05/05 4:24 PM

You would also get a databse error when you attempt to insert 40 characters into a field that is VARCHAR(35), or if you attempt to insert 'foo' into a field that is INT. A datatype could be viewed as a type of check constraint (maybe?).

I guess it comes down to how each RDBMS handles and identifies the error to CF.
doug s

doug s wrote on 11/06/05 3:59 AM

any one have suggestions as to the best(or any) way to validate one field at a time with business logic as was asked above? It would seem i need to extend util.ValidationErrorCollection? would I need a seperate method for each field if I need to validate each field seperately?

any direction would be appreciated
Doug
SOSensible

SOSensible wrote on 11/07/05 11:03 AM

Joe... any more thoughts about keeping the standard (non-human readable) exception message available at the same time as the dictionary based message?
Nando

Nando wrote on 11/07/05 11:46 PM

Ok, everybody can sing along if you'd like:

I want my ...
I want my ...
I want my ARF! TV

I really like these short video demos! And pouring through the source code. The combination helps make something new suddenly very accessible. Thanks!

Anytime you feel like making a few more ... they'd be very welcome!
Steven Ross

Steven Ross wrote on 11/15/05 8:39 AM

Hey anyone get relator tables working with Arf!? Or do you have to build your own cfc for that part?
Joe Rinehart

Joe Rinehart wrote on 11/15/05 8:42 AM

Steven,

By "relator" tables, do you mean many-to-many through a third table, like User, Role and UserRole (where UserRole basically has a UserId and RoleId columns)?

I've done in a few times, but it's not "automagic" yet - you have to use a CFC to represent the two, with User.hasMany(Userrole) and UserRole.hasOne(Role) (and the other way around for Role --> UserRole -> User).

I'm looking into HasAndBelongsToMany(), but haven't had time to code it.
Joe Rinehart

Joe Rinehart wrote on 11/15/05 8:43 AM

Ed / Others -

Custom validation is pretty straightforward - you can override the base Validate method, calling it to get the ValidationErrorCollection, and then writing your own logic that adds to the ValidationErrorCollection as needed.

I'll demo that soon.
Steven Ross

Steven Ross wrote on 11/15/05 8:49 AM

Yeah thats what I was wondering, thanks, I spent some time yesterday trying to get it to work and it appeared to work but, no data went in. Good to know. That would be a great feature but, I suppose it isn't a huge deal to code those cfc's.
Steven Ross

Steven Ross wrote on 11/16/05 8:56 AM

Hey joe why wouldnt this work for a relator table cfc? (It appears to work but for some reason the query is an update instead of an insert)

This table (ContactPropertyValue) has 3 columns (ContactID, ContactPropertyID, ContactPropertyValue) with primary keys on ContactID and ContactPropertyID

I know that your code is expecting a ContactPropertyValueID so I created a method to override it and it does what is below and like I said it seems to work except when I do a save the query is an update instead of an insert. Just curious if I am doing something wrong or if this is entirely impossible to do.

[code]
<!--- Campaign.cfc --->


<cfcomponent extends="net.clearsoftware.arf.ActiveRecord" output="false">

<!--- Don't remove this line of code --->
<cffunction name="getFinalSuper" access="private"><cfreturn super /></cffunction>

<!--- Add statements like <cfset hasMany() /> and <cfset belongsTo() /> here --->


<cffunction name="setContactPropertyValueID">
   <cfargument name="ContactPropertyID" type="string" required="true" />
   <cfargument name="ContactID" type="string" required="true" />
   
   <cfset this.setContactPropertyID(ARGUMENTS.ContactPropertyID) />
   <cfset this.setContactID(ARGUMENTS.ContactID) />

</cffunction>


</cfcomponent>
[/code]
Paul Carney

Paul Carney wrote on 11/17/05 11:03 AM

Hey Joe,

Just a quick note on the phrase Arf! - I see that it is now beginning to be used in the email world.

http://www.mipassoc.org/arf/

ARF - Abuse Reporting Format

I hope your idea doesn't get confused with a spam-stopping format! :)

Paul
Sam Clement

Sam Clement wrote on 11/24/05 11:59 AM

I just followed you suggestion of overriding the base validate() method. Very cool!

In the blogEntry.cfc you can just create a new method that calls the validate() method and adds business logic validation:

<cffunction name="validateObject" returnType="net.clearsoftware.arf.util.ValidationErrorCollection" >
<cfargument name="err" required="false" default="#this.validate()#" />

<cfif len(this.getTitle()) lt 10>
<cfset arguments.err.addError("title", "blogEntry.title.tooshort")>
</cfif>

<cfreturn err />

</cffunction>

Together with the custom dictionary feature, you can create a pretty slick validation process.
Joseph Lamoree

Joseph Lamoree wrote on 01/22/06 1:48 AM

I just watched all three videos. Thanks for spending the time to put those together. They're far more engaging than a README.TXT in the root of your software release. :)

Write your comment



(it will not be displayed)