ColdFusion developers have been evolving quickly over the last few years. Best practices and design patterns have come to the forefront, with several different frameworks emerging to help the community. Model-Glue is a Model-View-Controller (MVC) framework that was released in 2005. It has rapidly gained popularity in the ColdFusion (CF) community due to its ease of use and flexibility.
Model-Glue is what is known among software engineers as an event-based, implicit invocation framework. You use XML to declare event handlers, and these event handlers are called via a URL or form variable. In response, Model-Glue calls Model components to handle business logic chores, and then render View templates for the display.
Model-Glue 1.x has been well received and been used in many successful projects. But the CF world continues to evolve at a breakneck pace, and the creator of Model-Glue, Joe Rinehart, is already hard at work on its next iteration. This article is meant to give you a look at the capabilities of this new version, called Model-Glue:Unity.
What's changed with Model-Glue:Unity?
First, what's with the grandiose-sounding name "Unity"? It's called Unity because it brings together two other, complimentary ColdFUsion frameworks into a single, unified system.
The first of these complimentary frameworks is ColdSpring. ColdSpring is an Inversion of Control container for managing the dependencies in the Model of a ColdFusion application. As a bonus, ColdSpring also provides very useful features like Aspect-Oriented Programming capabilities. A full discussion of ColdSpring will be left for its own article. But the important thing to note is that Model-Glue:Unity uses ColdSpring to manage the dependencies of the framework components themselves. Not only does this make MG:U itself easier to manage, but it means all MG:U users can take advantage of ColdSpring with no additional effort on their part.
The other framework used in MG:U is Reactor. Reactor is an Object-Relational Mapping framework, similar in some ways to Java's Hibernate. Using a combination of an XML configuration file and database metadata, Reactor generates a huge amount of code automatically. The generated components follow common design patterns such as Table Data Gateway, Data Access Object, Transfer Object, and Active Record. Like, ColdSpring, a full discussion of Reactor requires its own article (or articles!). The takeaway here is that Reactor can automatically handle many of the common tasks involved in CRUD (create-read-update-delete) applications.
Model-Glue:Unity builds on the previous versions of Model-Glue, but incorporates ColdSpring and Reactor automatically. As a result, Unity brings some very interesting and powerful capabilities to the table.
Getting Model-Glue:Unity running
Getting Unity up and running is easier than ever. Download the MG:U zip file and unzip it into your Web root. This zip includes the MG:U core along with ColdSpring, Reactor, sample apps, and documentation. It also includes a handy "application template" to make it a snap to create a new application.
The application template comes with an ANT build file to automatically copy the template to a new directory. (Figure A)
|The ANT build script|
Just modify the target and the replace value and execute the build script. At this point you can navigate to the application in your browser and run it. You'll see a simple confirmation screen confirming that your application is up and running (Figure B)
Let's start by having a look at the MG:U configuration files. These are in the config directory within your application's base directory. You'll see three XML files there, one for each piece of the Unity functionality.
First have a look at the ColdSpring.xml file, shown in Figure C.
|The ColdSpring configuration file|
Here you'll see all the various configuration settings for MG:U. The first section, labeled modelGlueConfiguration, sets all of the core Model-Glue settings. The second section, labeled reactorConfiguration, defines Reactor-related settings like datasource name, login information, and database type.
Next, open up the ModelGlue.xml file as shown in Figure D.
|The ModelGlue configuration file|
This file is where you define the event handlers, controller message listeners, and views for your application. If you navigate into your controller directory and open up the Controller.cfc file, you'll see the first actual ColdFusion code so far (Figure E).
|ColdFusion code so far|
The Controller and Model layers of a MG:U application are implemented as ColdFusion Components (CFCs). This article won't go into detail about architecting the Controller and Model layers of a Model-Glue application, but a future article may. Right now we're interested in the new features that Unity offers, so let's continue.
The last configuration file in the config directory is Reactor.xml, which is shown in Figure F.
|The Reactor configuration file|
This file is used to tell Reactor about the relationships between the objects that you're mapping to the database. You can see the database schema in Figure G. Comparing the two should be fairly straightforward. You can see I have a Customer that has an Address. A Customer can also have one or more Preferences. It's a simple data model but it will be sufficient to demonstrate the new scaffolding capabilities in MG:U.
One of the nicest new features in MG:U is scaffolding. This works in a similar way to the scaffolding found in Rails. By using the database metadata that Reactor creates, MG:U can automatically build CRUD functionality for you with one line of code!
Continuing with our example, Figure H is a modified ModelGlue.xml file, and you can see I've added a scaffold tag inside my event handler block. Now, MG:U will automatically generate four dynamic event listeners: customer.list, customer.view, customer.edit, and customer.commit.
If we specify the customer.list event in the URL, you'll get a list of the Customers in the database (Figure I). You can see it outputs the Customers in a simple table, and supplies links for editing or deleting each customer.
|A list of customers|
If I click on the edit button for a Customer, I'm sent to the edit screen (Figure J). Again, you can see the underlying Reactor framework in use here. The edit form automatically handles the associated Address and Preference displays based on the relationships I defined in the Reactor.xml configuration file.
One of the powerful things about Reactor is its ability to automatically validate incoming data based on the database metadata. If a column is of type date in the database, Reactor validates the incoming field as a date. If a column is not null in the database, Reactor makes it required, and so on. If we try to submit the form while leaving out a required field like customer name, Reactor automatically generates a validation error collection that Unity displays back to the user (Figure K). Once the fields validate, the data is inserted or updated in each of the tables as needed. Reactor generates the SQL to handle this automatically.
|Validation error collection reported by Unity|
Customizing the scaffold
You might have noticed that the display for the scaffolds is very simplistic. You might also note that the form field names were formatted as the names from the underlying database columns, i.e. customername instead of Customer Name. As you would probably expect, you can customize these generated files to your heart's content. It's easy to add new styles or entirely different display code if you need to. Here's a quick example of customizing a scaffold.
In Figure L, you can see that I've added another scaffold tag specifically for the edit operation. I've also told Model-Glue to run the layout event, which will apply the default layout and style sheet to the output. This will make things look a bit more polished.
|Scaffold tag added|
Next, I'll move the generated form display file out of the scaffold directory and dropped it in my view directory. At that point I can open the file and alter the field names so that things like Customer Name display correctly. As you can see in Figure M, things look quite a bit nicer. Not only are the field names correct, but the default style sheet is applied. Model-Glue:Unity allows for a great deal of flexibility and customization of how the scaffolding works, if you need it.
|A better presentation|
Keep your eye on the prize
I've only scratched the surface of what's possible with Model-Glue:Unity, but I hope this intrigues you enough to keep your eye on this evolving new version. By leveraging ColdSpring and Reactor, Unity is reaping the benefits of the work of multiple groups of CF developers. Watch for some future articles that will go into more depth on ColdSpring and Reactor, both of which are great options for any ColdFusion application, not just Model-Glue apps. I'll also go into more detail on Unity itself as the final release draws closer. Stay tuned!