Enforcing the use of routes in CFWheels

If you really like routing (you’d find that really funny if you’re Australian) and want to enforce their use in all linkTo(), urlFor() and startFormTag() function calls.. Do as I do..

Put the function below into your /controllers/Controller.cfc

<!--- /controllers/Controller.cfc --->
<cffunction name="urlFor" access="public" output="false" hint="ensure routes are used for all urls">
    <cfif ! StructKeyExists(arguments, "noroute") && ! ( (StructKeyExists(url, "controller") && url.controller == "wheels") || StructKeyExists(arguments, "url") )>
      <cfif ! (StructKeyExists(arguments, "route") && Len(arguments.route) gt 0)>
        <cfthrow message="Please use a route rather than an action.. Thanks!">
      </cfif>
    </cfif>
    <cfreturn core.urlFor(argumentCollection=arguments)>
  </cffunction>
</code>

This overrides, the core urlFor() method, checking for the existence of a route argument.. UNLESS, the controller is “wheels” which probably means you’re using the test framework or managing a plugin. There is also a way to bypass the route nazi.. by using the noroute=true arguments.

Happy routing.. Teehee!

Run your CFWheels database migrations automatically on application start

It’s no secret that I’m a massive fan of the Coldfusion on Wheels framework.. and there are a couple of tools that I use in my deployment process that are invaluable to me.

One of those is the DBMigrate plugin. I recently came up with a way to automatically migrate to the latest database version when the application first starts.

This can be useful/essential when:

  • Your deployment process doesn’t use post-deploy hooks
  • You want to make your application more portable
  • You want to simplify your deployment script

Essentially, it calls a couple of the plugin’s methods whilst doing a little array-fu.

/events/onapplicationstart.cfm

<cfscript>
// migrate database
_dbm = {}
// create a pointer to the dbmigrate plugin
_dbm.plugin = application.wheels.plugins.dbmigrate
// create an array of available migrations sorted by version in descending order
_dbm.available = []
for(item in _dbm.plugin.getAvailableMigrations()){
_dbm.available.Append(item.version)
}
ArraySort(_dbm.available, "numeric", "desc")
// migrate to the most recent version
_dbm.plugin.migrateTo(_dbm.available[1])
</cfscript>

There are a few caveats:

  • It will execute every time the application loads OR is manually reloaded via the reload=true parameter (though it’s fairy lightweight when there are no migrations to execute)
  • It will execute on every server in your cluster
  • There is (currently) no error handling
  • It could disable your application if your migrations fail