Validating data in ColdFusion 9: Part II

Word Count: 387

Earlier today I wrote an article on data validation in ColdFusion 9. Tonight I was working some more on my new project when I found another thing that kinda bugged me. As you probably already know you can declare a property and automatically have getters and setters created for them. This is really great except for when I need to validate what the user is entering.

In this example I have a user component with a bunch of different properties, one of which is date of birth. This is going to be a date so we want to make sure we declare this of type date. So far so good except when it comes time to collect data from the user. I know we would probably never do this but let's just say for this example we display a text box to the user and ask them to enter their date of birth. The real problem comes when we need to set the data. If the user enters anything other than a valid date you get the following error.

The value cannot be converted to a date because it is not a simple value.

I understand why its doing what it is doing but the real problem comes when you need to validate what the user is entering. No longer can we validate the data before its persisted we now need to validate it before it's set which really throws a wrinkle in to what I am trying accomplish. Anyone with some thoughts on this please share because I am kinda bummed out seeing this behavior. I know I can overwrite the setter but tends to be a pain in the butt and probably my only option for anything thats a non string.

Comments

#1 Posted By: Dan Vega Posted On: 9/24/09 11:06 PM |
Author Comment
I guess I don't have to explicitly declare it a date. My thought was I would have to do that if this was an ORM entity but I think I can declare the cf type and the sql type so that would solve that problem. If your accepting user input in the scenario above do you just declare it a string and use your validation package to check the type?
#2 Posted By: Devin Posted On: 9/24/09 11:33 PM
Declaring a CF type is equivalent to creating a typed argument in tag form: <cfargument name="dob" value="type">. I believe even the same validation is performed. So if you don't want the automatic validation you can just as easily do:

property any dob;
or just:
property dob;
#3 Posted By: Henry Ho Posted On: 9/25/09 4:13 AM
Yes, and that's why those validators are not very useful in some (or most, to some) situations. I tried them, and now I ignore them.
#4 Posted By: Dan Vega Posted On: 9/25/09 8:47 AM |
Author Comment
Devin - I think that is my plan going forward. There really is no need to set their type anyways, thanks!
#5 Posted By: Micky Dionisio Posted On: 9/25/09 6:41 PM
Dan-

My 2 cents. This approach ties the user to implement their validation at the business object level, more specifically within setters. Maybe push around the idea of decorating the biz object at startup time and only validating via a convention when some type of framework construct is called. for instance:

var user = new User();
user.setAge("1984");
//do some other setters here...

//now allow the user to call a conventional function that validates using your framework.
user.validate();

//the maybe call these convenience methods?
user.isValid();
user.getErrors();

Reason is I should be able to get/set as needed and would want domain level validators to take care of the rest. I think you're framework could lighten the load of creating those domain level validation objects. Especially since you've got it programmed to an interface one could possibly even create his/her own custom validator by extending one you've already written.

I feel like I'm blabbering so apologies if this isnt clear.I'd be happy to trade emails for clarification

Cheers
#6 Posted By: tony petruzzi Posted On: 9/26/09 10:04 PM
another problem is when you want to validate only in certain situations. for instance, you want to make sure that the password is of a certain length, but only for creating a new user and not for editing an existing one since existing users might not want to change their passwords. with the validations in the CF9 built in ORM, how do you go about doing something like that?

i haven't tried out CF9's ORM yet, but i've been following closely to see what everyone is writing about it. i really don't like the fact that you can only access one datasource per project with it nor do i like what i'm seeing about the validations.

at this point the ORM isn't something i think i'm ever going to use.
#7 Posted By: Dan Vega Posted On: 9/28/09 9:08 AM |
Author Comment
@Micky - I have some good ideas about that and If you get a second I encourage you to check out the project - http://hyrule.riaforge.org. You actually end up passing in your domain objects to the validator for a couple of reasons but mainly to keep loose coupling between the validation framework and the business object.

@Tony - I think you really need to separate ORM and validation. The hibernate implementation in CF9 is really outstanding and in my opinion its worth looking into. You can do your own validation or use another validation framework to do that for you.
#8 Posted By: Micky Dionisio Posted On: 9/28/09 10:47 AM
Dan-

Yep I did last week, unless there has been updates to it since then I'd be happy to download the update. While th eloose coupling is awesome, it would still be cool if there was a way to wire up that relationship automatically instead of having to create two objects then pass one into the other at runtime. That way the domain is still loosely coupled as you said but the implementation saves me keystrokes since I will probably know before hand what validator belongs with what business object. If not I still have the flexibility of switching validators out when needed.

Also I will 9 out of 10 times probably want to create my own custom validator that extends yours since I'd need to validate composite relationships as well. ie -User has a address and the address must exist before persistence. So along with my string validation I'd also want that type of validation in the same place but still letting the composite biz object validate themselves. For instance:

So if im in the user validation obj:

//do some simple property string validation

//then do some composite validation that delegates to its own validaiton object.
if not user.getAddress().validate(){
//add to errors collection
/then return false
return false;
}
#9 Posted By: Dan Vega Posted On: 9/28/09 1:13 PM |
Author Comment
Micky - I have some ideas after talking with another pretty smart guy on how I can autowire the validation stuff. The challenge is making it easy to autowire the validation into 2 different scenarios. In 1 scenario you have a basic application that has domain objects, in another you are using ColdFusion 9's hibernate integration. The project is still new so once I can start to work this code in to some actual projects we will be able to solve some of these issues.

As far as custom validators that is one of a few issue s that need to be addressed. In the example of our user component we may need to make sure the username is unique. That would be a custom validator and I need a way to work those in.

There is new code on my local machine but I can't release it for a little while and I will just have to leave it at that.
#10 Posted By: Micky Dionisio Posted On: 9/28/09 1:39 PM
D-

Sounds good man, will keep an eye out for the next release.


Post Your Comment

Leave this field empty







Show Captcha

If you subscribe, any new posts to this thread will be sent to your email address.

Copyright © 2007 Dan Vega | BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.