Reactor Validation Part II

Word Count: 90

In our last tutorial in this series we setup our ReactorValidation application. In part II we will dig deeper and begin to learn how reactor validation works. We are going to add the following code to the top of our editContact.cfm file. This piece of code will handle form submission, validate, and redirect if save is successful. First view the entire code and then we will break it down further. You can download the updated files by clicking the download link below.

<cfif structKeyExists(form,"submit")>

   <cfset contactRecord = application.reactor.createRecord("contact")/>
   <cfset contactRecord.setContactId(form.contactId)>

   <cfset contactRecord.setFname(form.fname)>
   <cfset contactRecord.setLname(form.lname)>
   <cfset contactRecord.setAddress(form.address)>
   <cfset contactRecord.setCity(form.city)>
   <cfset contactRecord.setState(form.state)>
   <cfset contactRecord.setZip(form.zip)>
   <cfset contactRecord.setPhone(form.phone)>
   <cfset contactRecord.setFax(form.fax)>
   <cfset contactRecord.setEmailAddress(form.emailaddress)>
   <cfset contactRecord.setWebsite(form.website)>
   
   <!--- validate the contact --->
   <cfset contactRecord.validate() />
   <cfset errorCollection = contactRecord._getErrorCollection() />
   
   <cfif NOT ErrorCollection.hasErrors()>
      <!--- save the contact and redirect to their view --->
      <cfset contactRecord.save()>
      <cflocation URL="index.cfm" addtoken="false"/>
   </cfif>

</cfif>

The first piece of code here just sets our contact id. If we are adding a new contact the id will be 0 and reactor will understand that the create method needs to be called instead of the update method. Well how does it know this you ask, keep reading. The rest of the code here just sets all of the contacts information based on the form submission.

<cfset contactRecord = application.reactor.createRecord("contact")/>
   <cfset contactRecord.setContactId(form.contactId)>

   <cfset contactRecord.setFname(form.fname)>
   <cfset contactRecord.setLname(form.lname)>
   <cfset contactRecord.setAddress(form.address)>
   <cfset contactRecord.setCity(form.city)>
   <cfset contactRecord.setState(form.state)>
   <cfset contactRecord.setZip(form.zip)>
   <cfset contactRecord.setPhone(form.phone)>
   <cfset contactRecord.setFax(form.fax)>
   <cfset contactRecord.setEmailAddress(form.emailaddress)>
   <cfset contactRecord.setWebsite(form.website)>

As promised we will take a look at how Reactor knew which method to call. If you look in the reactor.project.[appname].DAO folder you should find a file called contactDAO.cfc. In that file there is a method called save which is the method we end up calling and there you will see the following code. As you can see Reactor knows what method you are trying to call.

<cffunction name="save" access="public" hint="I create or update a contact record." output="false" returntype="void">
      <cfargument name="to" hint="I am the transfer object for contact" required="yes" type="reactor.project.ReactorValidation.To.contactTo" />
      <cfif IsNumeric(arguments.to.contactId) AND Val(arguments.to.contactId)>
         <cfset update(arguments.to) />
      <cfelse>
         <cfset create(arguments.to) />
      </cfif>
   </cffunction>

Next we actually call our validate() method. This is the method that will validate our users data.

<!--- validate the contact --->
<cfset contactRecord.validate() />
<cfset errorCollection = contactRecord._getErrorCollection() />

So what does the validate method actually do? If you want to you could take a look at the contactValidator.cfc file in your reactor project folder but here is the summary. Reactor is going to read your database schema from there the magic happens. We are mainly checking for 3 things.

  1. If it is a non null field was any value provided.
  2. is the data type of the value correct
  3. does the value fit within the constraints of the length

If at any time an error is found it is added to an array located in reactor.util.ErrorCollection called ErrorCollection of course. So if no errors have been found, save the record and lets redirect the user back to the view page.

<cfif NOT ErrorCollection.hasErrors()>
      <!--- save the contact and redirect to their view --->
      <cfset contactRecord.save()>
      <cflocation URL="index.cfm" addtoken="false"/>
   </cfif>

If there are any errors, displaying them to the user is easy.

<cfif IsDefined("ErrorCollection") AND ErrorCollection.hasErrors()>
   <cfset errors = ErrorCollection.getTranslatedErrors() />
   <ul>
   <cfloop from="1" to="#ArrayLen(errors)#" index="x">
      <cfoutput>
         <li class="error" style="color:red;">#errors[x]#</li>
      </cfoutput>
   </cfloop>
   </ul>
</cfif>

I promised you we would farther in to Reactor validation and we have, in part III we will learn how to extend our base validation object and create custom validation.

Comments

#1 Posted By: Julian Halliwell Posted On: 8/21/06 5:22 AM
Although it's a logical dependency, calling the _getErrorCollection() method on a Record object will return a type error unless you have previously called the validate() function. Just for anyone else like me who doesn't always follow instructions step by step.


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.