Infinite entities, cfgrid and one cfc to handle the data
ColdFusion 9, ORMWhile writing SpreadEdit I wanted every entity to be editable via cfgrid. In particular I thought it would be cool to have one cfc on the back end to process the data from cfgrid no matter what entity it was working with. With ColdFusion 9 and ORM this proved possible and is pretty cool, check out the screencast. Code the other side of the embed.
Here is the code for genericGrid.cfc:
Thoughts on first Flex/Air app
Flex, ColdFusion 9, AirRecently I launched my first Flex-based Air application. Here are my thoughts:
Flex apps are real apps
Previously I thought Flex applications where simply the V in an MVC framework with a bunch of fancy UI widgets. Now I see differently and the value of a Flex MVC framework becomes clear.
Value-Objects and ORM is beautiful
I used the Data/Services feature of Flash Builder 4 to get a quick start on the application. The object it creates can be sent to ColdFusion and saved to the database by simply using entitySave(). Powerful stuff. Exactly how this is used is dependent on the whole architecture architecture. I ended up having some Controller work in both Flex and ColdFusion, whether good or bad is for another day, because I needed to send some emails and notify other users via Messaging. I now see where the CFaaS feature could allow Actionscript programmers to add the features they need like email to their applications without writing any ColdFusion.
Messaging, Gateways and Config Madness
The messaging feature of Blaze DS/ColdFusion combined with Flex was the deciding reason for writing this application in Air. Its ridiculously cool to use but also ridiculously hard to set up. A whole bunch of XML files, Event Gateways, other gateways. Definitely an area that could be improved in the ColdFusion administrator and documentation.
Spark looks good out the box
One thing I did not like about Flex 3 apps was the default look. The new Spark look is great and looks lovely straight away. I have done almost no design for this application, the users like the look and feel, and overall that has been a big timesaver.
Overall I have really enjoyed writing my first Flex application. I'm definitely not an expert in it but was able to make a great desktop application with it. I can see that I need to learn more about architecting Flex applications to truly get the full benefits of it.
In ColdFusion 9, what isNull() and what is it good for
ColdFusion 9ColdFusion 9 brings us a new function called isNull. But, you may say ColdFusion doesn't support null's and you would still be mostly right. As of ColdFusion 9 certain objects can be null. Sound tricky? Here are a couple handy uses for isNull.
Working with caches
When using CacheGet if the id you pass does not exist then the returned object will be null. Its therefore best to check after getting the data:
When using either entityLoad with unique=true or entityLoadByPK which is required to change values of an existing object (in db terms: a row you want to do an update on) if the id you pass in does not return an object then you get a null object back.
Checking to see if a variable exists
While not an object its possible to check for an undefined variable with isNull. (Queue debate on which is quicker/better for determining if a variable exists isNull, isDefined or structKeyExists!)
isNull is a minor addition but one that proves quite useful when working with caching and/or ORM.
Thoughts on my first ColdFusion 9 application going into production
ColdFusion 9, ORMI recently released my first application built with ColdFusion 9 to production and it took full advantage of some of the new features of ColdFusion 9. Overall these features sped up development and have nudged me to become a better developer.
ORM
Damn this is cool. Create a new cfc with persistent=true, write all the needed properties, and as long as the ormsettings include dbupdate=update and ormReload() is called all the database table creation is complete. Then use entityNew, entityLoad and entitySave to work with the object(s). Making changes to the model is as simple as adding a property. Setting up event handlers to automatically deal with audit data improves the applications quality and is also damn cool! That added with the code assist from CFBuilder makes development very rapid.
But beyond the ease and speed I also feel that ORM has made me a better object-oriented developer as I noticed I finally really stopped thinking about tables and instead objects.
Improved CFScript
After all these years of loving writing everything CF in tags it feels a little weird to switch to loving script but its less code, cleaner and easier to read. Now I love using cfscript for writing CF in the model and controller layers. For views good old tags are still my preferences. The only disapointment is that not all tags are available in script (and way fewer than as suggested by Ben Forta). I hope that will be enhanced in either 9.0.1 or 10.
Caching
This application retrieved a lot of information from third parties so to increase speed and reliability I did a fair amount of caching. It doesn't get much easier than using cachePut and cacheGet which work with every data type (xml, structures, strings, etc).
Virtual File System
While I have not done any fully scientific, load balanced tests my quick tests show code running faster from the VFS which makes sense as its in RAM. ColdFusion treats the VFS just like any other file system which makes using the VFS extremely easy. The only problems I encountered came about if the VFS connection was not closed properly and that file could then often not be used until a restart. To accomodate for this I added try/catch around use of VFS where an error might occur and closed the files in the catch.
There are many, many more features of ColdFusion 9 and I tried to cram as many as possible into my Best of ColdFusion 9 submission SpreadEdit as possible but this application only used the above ones!
Overall I've really enjoyed building applications with ColdFusion 9. Its definitely faster in both performance and development, especially when combined with ColdFusion Builder. I think it may well shift how we build applications.
How in one line to extend ColdFusion by writing CFC's
ColdFusion 9There have always been ways to extend ColdFusion through custom tags (and its variations like cfmodule) or by adding a library cfc or by including a file before every page.
I now present another way;
- a way to write a cfc
- place it in a folder
- and call it via the new operator.
And its all done by one setting:
this.customtagpaths = pathToExtensionFolder!
Lets see it in action. First, set up an Application.cfc like so:
Then in the langaugeExtension folder add as many cfc's as you want for my example I included one called Invoke.cfc (yes, I've wanted a script based version of this for a while! ;) ):
In the root folder I created a test.cfm with the following code:
Being in the root folder the first line should always work. Nothing exciting there. But whats cool is line 4 where variable i is set with no path to Invoke(). And it works. Here is a screenshot:

Next I created a sub folder structure to see if this would still work further down the chain.

And here is the code for dirB/test.cfm:
Which works as well! Here is its screenshot:

You can also place extra CFCs in the servers root CustomTags folder and use new on them. I think this is a bad idea. Its better to write applications that can be dropped anywhere and are not dependent on special server set ups.
So a pretty easy way to more natively expand upon the ColdFusion language and while I mention this.customtagpaths above it is also possible thanks to the new operator introduced in 9.
Using ORM Event Handler to easily and automatically add audit information
ColdFusion 9, ORMUsing the event handling features in ORM in ColdFusion 9 makes it easy to automatically add audit information such as last updated and last modified by to all objects, well technically tables, in the database. I'm about to launch my first ColdFusion 9 application and the technique below has worked well and sped up development.
Step 1: Decide on audit colum names
There really is no right or wrong way here. Go for something readable and easily understandable (for those lucky future developers who will look at your code!). Once you pick them add them as properties to your CFC:
Step 2: Turn on Event Handling and Hander
In your Application.cfc in addition to ormEnabled=true, turn on event handling and an event handler like so:
this.ormsettings = { eventHandling=true, eventHandler="myEventHandler" };
The eventHandler points to a valid CFC "myEventHandler.cfc" which is what we will create next.
Step 3: Create an Event Handler CFC (See I told ya!)
{
Step 4: Add code to preInsert and preUpdate functions
The preInsert and preUpdate functions in the event handler CFC are the last functions that get run before ColdFusion hands over to Hibernate for persistence (a fancy way of saying saving to database). All of the functions in eventHandler take in the entity as an argument called entity (if you are new to cfscript within the parenthesis its saying a type of any and an argument called entity). We simply call the various functions and pass in the values. I found I got an error at first matching the session userID to createBy and lastModifiedBy and needed to use JavaCast. [Update Feb 6 '10: This bug is scheduled to be fixed in 9.0.1] After making a change to myEventHandler.cfc run ormReload() (I've gotten used to having this in onRequestStart and commenting it out when not needed).
The preUpdate function is very similar except just has the setLastModifiedBy and setDateModified calls. If all your entities don't have the audit properties/columns use this technique for checking if the function exists.
Lets see it in action.
Using the Team object from above:
Thats all the code needed. Here's a screenshot of the database after insert that shows all the audit data.







Loading....