Any interest in a Validat factory CFC and a IsValid() adapter?

5 views
Skip to first unread message

Dennis Clark

unread,
Feb 25, 2009, 8:13:10 PM2/25/09
to Validat
Hello all,

I'm a CF backend coder and I've been working on a web application
project for the past 5 months. I chose to use the Model-Glue framework
for the application with Transfer as the ORM. I had used both Model-
Glue and Transfer in previous projects but this project is the first
one where I have used them together.

My first Model-Glue application used Reactor as the ORM. The Reactor
ORM includes validation functionality so the Reactor ORM adapter in
Model-Glue performed validation for me prior to committing any changes
to the database. Transfer does not include validation functionality so
I had to look elsewhere for validation, which is how I came across
Validat.

I installed Validat and found that it was exactly the sort of thing I
was looking for in a server-side validation framework. I wrote a
simple ValidationController to listen for "validate" messages from
Model-Glue and invoke the validator. I included a "validate" broadcast
at the top of every commit event and a ValidationError redirection
result at the bottom of each such event to pass control back to the
corresponding form event when validation fails.

Adding validation to a new form is now quite easy for me: I define the
rules for the dataset in the validat.xml file, add a couple of lines
to ModelGlue.xml, and paste a snippet into the form's view to display
any available error messages.

In the process of integrating Validat into my project I made a couple
of tweaks to Validat.

First of all, I wrote a ValidatFactory.cfc to create Validat instances
for me. This is great in Model-Glue because I can then use Model-
Glue's ColdSpring to set up Validat's ColdSpring without mixing the
two together. To illustrate, here is how to use my factory with the
examples/_common/coldspring.xml bundled in Validat:

<bean id="validatFactory" class="validat.validatFactory" init-
method="setup">
<property name="engineConfigXmlPath"><value>/validat/config/
coldspring.xml</value></property>
</bean>

<bean id="validat" factory-bean="validatFactory" factory-
method="getValidat">
<constructor-arg name="rulesConfigXmlPath">
<value>_config/validat.xml</value>
</constructor-arg>
</bean>

The first declaration is for the Validat factory. When this bean is
set up, it will create the ColdSpring instance that Validat needs to
function. If the property declaration is omitted, the bean will
instead use its "parent" ColdSpring instance for creating Validat
objects.

The second declaration uses the factory bean to create a Validat
instance. Since configuration of Validat instances is now separate
from configuring the Validat framework, I can use the same framework
instance to create multiple Validat instances with different rule
sets. I could even have a single instance of the framework in the
server scope shared across multiple applications, each with its own
Validat instance in the application scope!

To make the factory work, I only had to add a new bean definition in /
validat/config/coldspring.xml, and change the access of parseConfigXML
in Validat.cfc from private to package. The changes should be fully
compatible with existing code.

My second tweak is a new validator CFC that works as an adapter for
the built-in IsValid() function. Since the IsValid() function performs
so many different kinds of validation I thought it would be nice to be
able to use it from within Validat.

If any of you know what the heck I am talking about and are
interested, let me know and I can send you the code for the two CFCs.
I can even show you my MG controller, but it's pretty basic.

Cheers,

Dennis

Chris Blackwell

unread,
Feb 26, 2009, 12:38:32 PM2/26/09
to val...@googlegroups.com
I'd definately be interested in taking a look at this.  how about a simple MG example app that uses validat?

Chris

2009/2/26 Dennis Clark <boom...@gmail.com>

Dennis Clark

unread,
Feb 27, 2009, 10:09:35 AM2/27/09
to val...@googlegroups.com
Sure, a MG example app would be a good way to show how it all works.

The only example MG application I've seen so far that I've liked is the Widget example. It relies on scaffolding so I would not be able to add a "validate" message broadcast to commit events without overriding the scaffolding. But, now you've got me thinking...

Looking at the source for Model-Glue, I noticed that the implicit ORM controller is registered after all the explicit controllers in ModelGlue.xml. This means that if a custom controller in the ModelGlue.xml listens to the "ModelGlue.genericCommit" message used by the scaffolding, the custom controller would process the message before the implicit ORM controller does. This is perfect for validation, as the listener method in the custom controller could use Validat to validate the inputs for the commit before the commit is attempted. If validation fails, the ValidationError result will redirect the request and so stop the actual commit from being attempted.

In order to have Validat to step in for the limited validation in Model-Glue in this way, the validator would need to return an error collection that is compatible with the one used by Model-Glue. Validat's error collection is a different to that used by Model-Glue but is similar enough to make conversion fairly straightforward. I'm actually thinking of creating an ErrorCollectionAdapter that extends Model-Glue's ValidationErrorCollection but uses Validat's ErrorCollection under the hood.

I've solicited my local ColdFusion user group for a simple CF application to convert to Model-Glue and use as a basis to demonstrate all the little tricks I've come up with. If you have a simple app that you think might make a good example for Model-Glue/Validat let me know and I'll take a look at it.

Stay tuned and I'll let you know of my progress with the example app and the Model-Glue integration.

Cheers,

-- Dennis


On Thu, Feb 26, 2009 at 12:38 PM, Chris Blackwell <ch...@team193.com> wrote:
I'd definately be interested in taking a look at this.  how about a simple MG example app that uses validat?

Chris

2009/2/26 Dennis Clark <boom...@gmail.com>


Hello all,  

[...]

In the process of integrating Validat into my project I made a couple
of tweaks to Validat.

[...]

Dennis Clark

unread,
Mar 25, 2009, 11:27:05 AM3/25/09
to val...@googlegroups.com
I have integrated my Validat stuff with Model-Glue 2 and the Widget example app, and uploaded it to a new RIAforge project that I called Walidget. I have not yet created a ZIP download but the source on SVN is stable enough for others to try out.

I encourage anyone who uses Validat to download the code from SVN and take a look at it. If you want to look at the code but don't know how to use an SVN repository, email me directly and I'll supply you a ZIP file. I'd apprecate any feedback on the Validat addons or the Model-Glue integration.

With the recent stirring on mailing lists and blogs about Model-Glue, I'm likely to migrate my Walidget application to Gesture (Model-Glue 3) in the coming weeks in the hopes that it will be useful in bringing Gesture closer to release.


In addition to the features I already mentioned, Walidget includes a "compare2" validator to perform a relational comparison (lt, gte, neq, etc.) of a field against a second field in the dataset. I used the Strategy design pattern to write one validator CFC (validateCompare2.cfc) for three different validator beans in ColdSpring (validateCompare2Numbers, validateCompare2Strings, and validateCompare2Dates). The string variant has an optional caseSensitive argument, and the date variant has an optional datepart argument.

Here's how I use validateCompare2Dates in an example form:

	<validationRules>
<rule name="compare2datetimes" validator="validateCompare2Dates">
<arg name="datepart" value="s" />
</rule>
</validationRules>
<dataSets>
<dataSet name="widget.Widget">
<dataElement name="OrderDate" required="false">
...
</dataElement>
<dataElement name="ShipDate" required="false">
...
<assert rule="compare2datetimes">
<arg name="resultIfSecondValueMissing" value="noOrderDate" />
<arg name="operator" value="gte" />
<depend name="secondValue" value="OrderDate" />
<message name="invalid" value="The ship date must on or after the order date." />
<message name="noOrderDate" value="The ship date must not be provided without an order date." />
</assert>
</dataElement>
</dataSet>
</dataSets>

If I change the datepart value in the compare2datetimes rule from "s" to "d", the assertion would then ignore the time parts of OrderDate and ShipDate when performing the comparision.

The resultIfSecondValueMissing is optional and can be used to either generate a different validation message when the second value is missing or to force the assertion to pass when the second value is missing (use value="true").


Cheers,

Dennis
Reply all
Reply to author
Forward
0 new messages