Thursday, March 20, 2008

Model-Glue Tips and Tricks

  1. Turn off automatic reloading of your application

    This will greatly reduce the time the application needs to process all request. This is the way I develop Model-Glue applications. In your Model-Glue configuration (the "modelGlueConfiguration" bean in ColdSpring.xml), look for the "reload" property and set it to false:

    <property name="reload">

    Keep in mind that changes made to anything else but your views will require an application reload. For my approach to that, read the next tip.
  2. Use two browsers

    The basics of this point has to do with using one browser for your development and one for reloading the application. I suggest this since if your application keep session state, reloading the application from the same browser will reset the session while reloading the application from a different browser will not. If you turn the Model-Glue automatic reload, your application will run faster but you will not be able to see any changes made in your controllers or model. Once you made a change you will need to manually reload the application by invoking the "reloadKey" with the "reloadPassword" as defined in the ColdSpring.xml file. By default the "reloadKey" is set to "init" and the "reloadPassword" is set to "true". So you would reload by invoking "index.cfm?init=true". To take this further I add the following code to my onRequestStart inside Application.cfc to reload the application if you simply go to "/yourApplication/?init":

    <cffunction name="OnRequestStart" output="no">
    <cfif structKeyExists(url, "init")>
    <cfset structclear(Application) />
    <cfset structclear(Session) />

    <cfset onApplicationStart() />
  3. Turn on debugging

    Debugging is enabled by default but to turn it on or off you change the "true/false" value inside the "modelGlueConfiguration" bean in your ColdSpring.xml" file:

    <property name="debug">
  4. Use a custom ColdSpring bean for your configuration settings

    To store your own configuration values to be used throughout the application you can take advantage of Model-Glues " SimpleConfig bean. This bean configuration will go in your ColdSpring.xml file and look something like:

    <bean id="applicationConfiguration" class="ModelGlue.Bean.CommonBeans.SimpleConfig">
    <property name="config">
    <!-- The network path where the bartender templates are stored -->
    <entry key="networkPathToLabelTemplates">

    To access your applicationConfiguration bean, you would use:
    getModelGlue().getBean("applicationConfiguration", true)

    I usually do this inside the "init" method of my controller:
    <cfset variables.appConfig = getModelGlue().getBean("applicationConfiguration", true) />

    And use it later on with:

    <!--- Get the path to the label templates from the configuration --->
    <cfset var networkPathToLabelTemplates = variables.appConfig.getConfigSetting("networkPathToLabelTemplates") />
  5. Take advantage of an ORM framework such as Reactor

    Initial versions Model-Glue used to come with Reactor but do no longer. I found it is a little difficult for a novice to start using Reactor with Model-Glue. To take advantage of Reactor, you have to download it, unzip it and create a ColdFusion mapping called "reactor" that points to your Reactor directory. Next comes the Model-Glue configuration. You need to add the following bean definitions to your ColdSpring.xml:

    <bean id="ormAdapter" class="ModelGlue.unity.orm.ReactorAdapter">
    	<constructor-arg name="framework">
    		<ref bean="ModelGlue" />
    <bean id="ormService" class="reactor.reactorFactory">
    	<constructor-arg name="configuration">
    		<ref bean="reactorConfiguration" />

    And of course you need the "reactorConfiguraiton" bean:
    <bean id="reactorConfiguration" class="reactor.config.config">
    <constructor-arg name="pathToConfigXml">

    <property name="project">

    <property name="dsn">

    <property name="type">

    <property name="mapping">

    <property name="mode">
    Now you can take advantage of Model-Glue's built in scaffolding and generic messages (genericList, genericRead, genericCommit and genericDelete).
  6. Use event beans

    Event bean is a predefined CFC that will store values form your form. It works by creating a one to one relationship between your form values and getters/setters in your CFC. Once you have your event bean created you can populate it from everything in the form scope by using the makeEventBean function:

    <!--- Create an instance of the bean --->
    <cfset var completePrintJobFormBean = getModelGlue().getBean("completePrintJobFormBean") />

    <cfset arguments.event.makeEventBean(completePrintJobFormBean) />

    <!--- Trace the label data id field --->
    <cfset arguments.event.trace("labelDataID", completePrintJobFormBean.getLabelDataID()) />

    Creating event beans has to do with defining getters/setters and local variables for each one of your form fields. It can be a tedious process but thankfully there is the Rooibos Generation to do it for you by simply taking the names of your form fields and generating all the code for your. You can learn more about this at Dan Wilson's blog article about So you want to create a ModelGlue:Unity application? ( Part 3 ).

    To use your newly generated bean, you will have to add the bean definition to your ColdSpring.xml file:

    <bean id="completePrintJobFormBean"
    singleton="false" />

    Keep in mind that if your form changes, you have to regenerate the bean. If you do not care about reusing your beans through external consumers, such as Flex, I have written about an alternative approach in "Get All Form Fields in ModelGlue the Elegant Way".
  7. Use tracing to debug the value of your variables

    Once you have debugging enabled, you can add values to your debug output by using the event.trace() method:

    <cfset arguments.event.trace("myVariableValue", myVariable) />
  8. Split your configuration in multiple files

    You can tell ModelGlue to include different configuration files by using the "include template" directive. I use this approach to separate my events based on the action they are related to:

    <include template="./config/events/labelEvents.xml"/>

    Here is what the included files looks like:

    <event-handler name="overRideLabelData">
    <view name="body" template="frmOverRideLabelData.cfm" />

    <result do="strippedApplicationTemplate" />

// //]]>