Coldfusion On Wheels, the forgotten framework

One framework that was unfortunately not represented at the Frameworks Conference was Coldfusion on Wheels. Although it was heavily developed at first, it’s started to split off with some question of the direction it’s going in. The idea is that it will be a port of Ruby on Rails for Coldfusion. There are a lot of concerns that people put out about Rails structure, one of those being that it’s impossible to use it without the model layer bleeding into the controller. Coldfusion on Wheels at the moment is in a big state of flux, but ColdFusion on Wheels 0.6 Lite comes without the model layer at all. On my way home from the frameworks conference I decided to give this framework some time on the plane home and was pleasantly surprised with the status of the project, and the flexibility of the current version.

Getting it setup
Downloading the latest lite version of the framework requires no real setup actually. The current version must be in document root from what I have been able to gather though so keep that in mind. The core framework files reside in the “cfhweels” folder which can be removed from the main app and mapped in cf administrator.

Search Engine Safe URLs
One of the initial draws for me was to see just how the url rewriting works. For those unfamiliar with Ruby On Rails or CF Wheels, these two offer what’s known as search engine safe (SES) URLs where the URLs no longer have query parameters in them 9for the most part). For instance, instead of referring to a page like http://localhost/index.cfm?event=user.profile&id=123, a search engine safe URL might be something like http://localhost/user/profile/123. The end result of this is that it’s (supposedly) better for search engines and (definitely) better for the user when trying to type in URLs.

CF Wheels handles this in both IIS and apache (tested both to work) in their own ways. For apache it uses the familar .htaccess tag, while in IIS it relies on Isapi Rewrite. What’s important with both of these is that it’s optional, and requires no knowledge of how .htaccess or isapi rewrite rules work. Those files are static and do one thing but do it well. They translate a link like

http://localhost/user/profile/123

to something like

http://localhost/dispatch.cfm?wheelsaction=/user/profile/123

The key factor being that you can opt to use these safe URLs or not, it’s up to you. So what does this resolve to? Well that’s configured in the /config/routes.ini file. By default there are three routes already:
[cfm]

[/cfm]
What this means is that when this request comes in, it will go through those and find the first one it matches. In this case it’ll be the first one because it has 3 parameters, controller, action, id. Think of this as calling the user.profile action, to put it in fuseaction terms. In that action, there will be a variable defined, request.params.id, which contains the value 123 in this case.

To expand on that a little, you could easily add another route if we wanted the username in the url instead of the id. So if we wanted something like this:
http://localhost/user/profile/AdamFortuna
We could add another router in our routes.ini file that looks like this:
[cfm][/cfm]
The same user.profile action will be executed, but there will be a variable defined, request.params.username, with the value “AdamFortuna”. Sounds easy enough, doesn’t it? CF Wheels handles this completely internally using routes. Although I haven’t traced through the code for this, the end result is the same as rails.

Webserver setup
I grabbed this piece of code from the CF Wheels Google Group, which works on my 2.0.59 apache setup as well as the posters 2.2.x installation:
[xml]
ServerName cfwheelsroottest
DocumentRoot “C:/inetpub/devroot/cfwheelsroottest”

AllowOverride All

[/xml]
I like to edit my local hosts file so that 127.0.0.2 will resolve to the name of the site I’m working with as well. So locally I’ll go to dev.mysitename.com and due to the hosts file addition (note hosts file is in C:WindowsSystem32driversetchosts) this will resolve to my local website instead of the actual one. Easy way to test things locally. In order to get safe URLs setup in IIS, you must be able to modify the isapi filters and add in a new one. For shared hosting in IIS you might not be able to run this feature of wheels, but if you have control over this it’s a very easy install.

Form helpers
URL rewriting is one thing that’s helpful for it to handle, as otherwise there is a lot more work involved in getting something like this setup, but there’s one other very helpful feature that is so simple to implement in any language that it might be overlooked — grouping form inputs from a form in an easy to use manner. What I mean might best be explained with an HTML example. Lets look at a sample form for a user to signup for a site.

[html]





[/html]

When this is submitted, it’ll go to the user controller, and the create action with the contents of th form. Similar to the URL parameters above, they will be available in the request.params variable. Note the naming convention in there though — user[username]. Wheels translates this a little bit before it gets to your controller, and turns request.params.user into a structure containing username, email, password and password_confirmation. Does this sound like anything? request.params.user is a transfer object! If the UserDAO is cofigured in Coldspring and Reactor, you could do something like this to insert this record.
[cfm][/cfm]
With that one line in your controller, you’d technically have everything you need to insert the form values assuming the form is complete.

Putting it all together
To be realistic though, you have to take into account a few more things. Obviously this shouldn’t be run when they call the user/create page, it should be run when thy submit the form. Also, what if there are errors? What if we have more related fields so it’s not just dealing with the user but a few other things? Well, I’m not quite there yet in some of those cases, but we can make it a little cleaner. As I said, this version of cfwheels has no model components, it is ONLY a controller. The question is what do you want in your framework? Brian Koteks presentation on Designing framework agnostic models showed just how little the framework can handle, and how important it can be to have things defined in a service layer. So what if you use Cfwheels with this service layer? Turns out it plays pretty well.

First a little preliminary information about cfwheels setup. In the app/controllers directory, you’ll have controllers whose names match the controllers in your urls. So those requests to /user/create will go to /app/controllers/user_controller.cfc, with the create() method being called. Consider this the application logic that exists to execute your service layer. This would be in your controllers in Model-Glue, your circuit.xml (or act pages) in fusebox — that kind of logic. After that it will automatically run a view associated with that page (unless overwritten in that create() method). The view page that it would run is located in /app/views/user/create.cfm. So looking at that URL you can know you need to mess with the create() method and that other display page. What does that create() method look like?

[cfm]






[/cfm]

Whats this do? Well, if that user structure exists within the request.params structure then we create the new user, generate a message saying it was successful and redirect the user to a new page. Otherwise we get a new blank user object filled in with any defaults.

Without getting too far into how the service layer is setup, it’s basically the same as in Brian Koteks examples. our create() method in the service looks like this…
[cfm]


[/cfm]
This just passes on that value to reactor which does the real work. In my working examples this is done in a BaseService which is extended by the UserService, but I’ll get more into that another time, once I figure out how to get error handling and multiple table inserts working easily.

CF Wheels is certainly a lot farther along than I would’ve thought it to be. Although it has no model components for which rails earns a lot of it’s fame, that can be easily substituted with a service layer generated by coldspring and reactor.

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments
Hey, thanks for taking the time to look at CF On Wheels!

I’m currently in the process of building the ORM for it and one option I’ve been considering is to just build a wrapper around Transfer or Reactor. Any thoughts on that, does it make sense to do? If so, which one do you think would be the best option?

Any ideas and input is very much appreciated :)

Hey Per! Great work so far. Saw that the wiki was being updated recently so thought something was coming and I’d better prepare. ;)

I haven’t had a chance to mess with transfer, so I can’t say how that one would be, but Reactor fits well with activerecord. I think by just copying the transfer objects values into the this scope of the bean object you’d have a decent rails syntax; but that would probably create a lot more problems. It depends on just how close you want the cfwheels syntax to be to rails. I’m fine with using getters/setters on my objects instead of just dot notation though, but it’ll probably be a matter of preference. Of course that’s assuming I don’t have to actually write those getters/setters. :p

As far as creating a wrapper for them, I think it’d be possible to create a service layer for them that cfwheels could interact with. This service layer could have everything injected by coldspring, so the only code generation needed would be the coldspring.xml, the blank service object that inherits everything from the base service, and maybe the reactor.xml file. I really like this idea, and the cool part is that it’d be transferable to any framework.

As for calling it, there might be an adapter for working with this service layer in wheels, but that’d be more for creating a familiar rails-like syntax than anything else. I’d be perfectly happy with a rails-like controller layer, then a tightly integrated reactor/cs layer in the for the model. I think it’d encourage people to write a better controller/service layer too, if it’s there by default. The cs/reactor implementation mentioned here is available in public repo here, although it’s just test code of course.

I do think it’d be possible to generate the models in this manner, since it’s Reactor that will be doing the bulk of the generation. I don’t know if I like the rails naming scheme for database tables, but it could be mapped out and written to a reactor.xml file. If the person writing the ap has different db naming scheme they’d have to fill in reactor.xml for themselves maybe?

Hey Adam,

Thanks for the writeup! I think this is the first major writeup I’ve ever seen on Wheels and you did it justice, thanks!

If you download a previous version, say 0.5.2 you’ll see a whole model layer in there, complete with Rails famous has_many, belongs_to, etc associations, as well as a slew of form helpers that would automatically read from the model and populate the fields (just like Rails). I wasn’t really happy with the performance of the models, though. To do them justice they should really return records as arrays of objects that just killed the performance. I split the models out and went the Lite route so that others could plug in their own model and not blame Wheels for poor performance. ;) Per’s going the model route and has made amazing progress.

As the controller package it’s pretty efficient right now, averaging less than 15ms for just the bare framework - almost no overhead at all. And not spending all day setting up XML config files is a big plus for me.

Thanks again!

I definitely understand what you mean about that array of objects dilemma. I tried using that feature in Reactor and it was equally slow when dealing with large record sets. Maybe in Scorpio (or bluedragon/railio/something else) the object creation of these is faster, but doesn’t help now.

I was pleasantly surprised by how fast the controller layer is to be honest. :) I was seeing those runtimes around 15ms for the entire framework handling as well. For my hello world page though, sometimes it was 0ms. :p

I have to admit: I mostly abandoned CF months ago, because the CF biggies were totally focused on frameworks that needed extensive config files (”xml situps”). For me, CF was all about programmer productivity, and no one even seemed to recognize how productive CF on Wheels could be. So, I went over to Ruby on Rails, and I’ve not been sorry too often.

BUT — there are some things that ROR just doesn’t do well, yet. SQLServer support is spotty; MSAccess support is nonexistent. ROR doesn’t do well poking BLOBs into SQLServer, and the adapter doesn’t do Ruby Time SQLServer DateTime very well, either. Ruby’s user community is good, but very much oriented toward CS majors coming from Mac/Linux/Java backgrounds. There are several important packages that don’t run on Windows machines, too — acts_as_ferret comes to mind. There are some things you just can’t do from the Windows IDE, so you end up on the command line sometimes. Getting ROR into a corporate environment can be an issue, too, whereas CF is already there.

Right now I still use CF to store/retrieve images from the db, or to hook up to legacy MS Access db’s. If CF on Wheels gets their ORM worked out, would I switch back? It’s very, very tempting — especially if Adobe finally adds some decent support for image-file munging, and fixes some of their antique bugs.

Still, I don’t see Adobe headed that way at all. It’s all “add features”, not “fix bugs”, and “be more like Java”, not “programmer productivity.”

Ron

Very good points about rails. I remember at one presentation I went to about ruby the plugins he was demoing only worked on a mac (well, it was something that when you clicked on your trace it would open up that file in textmate). The draw for to the community is certainly powerful though, there’s a load of extremely smart people all seeming to work as a one huge unit. But in the end you don’t need a ton of people to make a framework great, rails after all was started by a small group.

I don’t know if you’ve been reading up at all about coldfusion 8 features, but they are adding support for image manipulation with this version to many peoples cheers. Aside from that the top thing I’ve heard is that just creating cfc objects will be MUCH faster which helps out with the OO heavy stuff, and maybe even some of the rails techniques. I’m still hoping they make XML a little easier to deal with, as every time it seems to be a lot harder than it should be to get anything done. Definitely seems like a lot of people want more java-like features though, but Hal Helms puts it dead on in A New Vision for Coldfusion in saying we should concentrate on what makes Coldfusion great, not just try to be more like java (well amongst other things in that article :p).

How ironic! The first 1/3 of the Rails “bible” is a story where a developer spends a morning at a customer’s and leaves with the 4th iteration of the application running. All the customer’s requests are added right there in her office.

Isn’t that the story Hal says ColdFusion ought to be telling? Used to tell?

Well, we tried.

Ron

Hmm, i took the article a different way. More that we can use Coldfusion to do exactly what that — spend the morning with a customer and come up with a few sample iterations. He argues that Adobe should be putting more emphasis on this than some of the advanced and optional topics like interfaces and constructors. I don’t get the impression he’s saying Coldfusion can’t do this, but just that the direction Coldfusion goes in should continue to lean towards the rapid application side rather than the java world side.
A truly great post. I’ve been checking out the cfwheels site lately to see if there’s new stuff but no progress. Nice to see Per still working away. I still feel though cfwheels has quite a few issues, certainly some worth considering. For me I’ve always wondered why a controller instance is created on every request. The controllers should be initialized once and placed into the application scope. Maybe though its done because the CFC’s are using the request scope.

My other concern is that I don’t get a modular framework with cfwheels. I can only have 1 controller and 1 action fire within a request. I’d like the capability to fire many within a request so I can reuse my action code and my views if needed. I had approached Rob with this question but his responses was using models.

I can’t wait to see though what changes Per and Rob has in mind for cfwheels. The framework has a ton of potential I just feel it has a bit of code bloat but thats most likely my lack of Ruby on Rails knowledge. A lot of the code there must come straight from Rails. As I was at the frameworks conference this year, it’d be very nice to have it make an appearance. Maybe I can make a presentation on it if not. Again great post Adam.

Hey Javier, thanks for the kudos.

I’m not too sure there’s a way to reuse controller without redirecting, but at least that’s an option. You can use redirectTo() to forward the user onto another URL in a nice way for one.

The other option is to put that reusable code in your helper — either the application_helper, or the controller specific helper. Seems like they’re basically local functions at that scope you can reuse code in. It does complicate reading over code having it in that many places, especially when there are model/service layer calls in both, but at least it can be centralized.

As for reusing views there is some mechanism in there for it at the moment. For instance, if in you’re making a form for adding/edit users you might create that form in the views/user directory and call it _form.cfm. That file can be included from other views using something like , which will output that page. This is one great way to make the code from those add/edit forms reusable.

Another option is from inside your controller. Say for instance you access the /post/list page in an application and it generates the html list of blog posts. Now assuming you add the necessary route, you could go to post/list.xml and it would go to that same controller function with that “xml” defined as matches your routes. Inside your post/list controller you could add a line like and that’ll output the xml equivalent. I think there are a few more render() options like , so if you wanted to render a different view within the current controller you could do so with . That won’t stop page processing of the rest of the controller, but the default post/list.cfm page won’t be included in that case.

Definitely think it’d be great for a frameworks presentation. I bet with more people supporting them there might be a call for a talk on them.

The reason the controllers are created on each request and not placed in the application scope is because anything you want available to the view should be set in the variables scope of the controller. The reason we do this is to make the code really simple and readable (as it is in Rails). Using this technique there is no need to pass variables out of the controller method for example (a bonus is you don’t have to worry about forgetting to var scope!).

I do have plans to use object pooling for the controller (as we currently do with model objects) but so far it’s not been a high priority.

Rails/Wheels is all about re-using code and keeping DRY. As Adam mentioned helpers and partials are some of the ways you can use to achieve this goal.

The fact that you only fire one controller/action per request also makes things simple (you can tell exactly where to find your code by looking at the URL bar for example)

Well, Adam, I’ve said right along that CF is still unequaled for producing Web PAGES. I find that Rails is superior, though, for producing a Web SITE.

Without a framework, CF’s strength becomes its weakness: too many pages get flirted out without regard to structure and maintainability. Rail’s strength (site structure) becomes its weakness when you really do just need a few static or nearly-static pages.

One other built-in weakness of Rails is that it really, really wants to be the root. If it isn’t, you’re constantly fighting the structure, I find.

Anyway, my hope for CF on Wheels is that it will combine the best of both: not only the elbow-room to slap a few pages out there fast, but also the wisely-chosen conventions to put rigor into the site design.

You guys should take another look at Wheels if it’s been a while. Per has been working pretty hard as of late, the documentation’s starting to come together, and the ORM system is rocking. hasMany(), belongsTo(), etc. work right out of the box. I think this can help the CF community out a ton…consider giving it another look and chipping in some time to help out.
Definitely worth another look! I haven’t been doing much CF lately unfortunately, but it’s definitely at the top of the list. Why there’s not a million active CF developers swarming around CoW (or any rails ColdFusion framework) is still a question mark for me.
Leave a comment

(required)

(required)