Mach-ii for newbies ? part2

Mach-ii for newbies - part2


Reading and manipulating data


Written by Trond Ulseth (



1. Introduction


Hello, and welcome back. This is the follow up to a part 1 (obviously), originally posted at ( If you did not read that one yet you probably should (or maybe not - what do I know? At any rate, I won't come after you if you don't).


A lot of things have happened since I wrote part 1. In the meantime I've been developing on my first real OO (Object Oriented) application. That application was written without using mach-ii or any other framework though.


One thing I feel I did not emphasize in part 1 (actually, looking back I see I did not mention it at all) is that the mach-ii framework is "created to help software development and maintenance using an OO style" (quote from In other words, to use and leverage the mach-ii framework you should (no - need to) understand OOP.


Remember in part 1 I suggested that even though we did not see the payoff of using mach-ii right away "we'll just have to trust that there will be some payoff for the extra work further down the road". After finishing that OO project I can definitely say that there is payback down the road. And looking at the improvements using the mach-ii framework would bring to that project had it been used, I see that the payoff would be doubled (or at least enhanced pretty much).


However - for now - OOP will not be the subject of this tutorial series. I've had a lot of positive feedback from the first part, but also some criticism. One of the critics was that I focused very much on the mach-ii.xml configuration file, while going pretty quick through the bean concept. While agreeing that understanding the bean concept is important, a bean is not a mach-ii specific subject, while the mach-ii.xml file is mach-ii specific to the highest degree. So that is the walk I'll walk and talk I'll talk for now.


Let me just quickly remind you of the disclaimer from part 1: "I am learning as I'm writing, or writing as I'm learning. I can therefore not give any guaranty that what I am doing is totally best practices, or that I have so much understanding of what I'm doing that I explain it as clear as could be possible. I'll try though to write in an easy to understand and slightly entertaining way."


Enough jabbering! Let's dive into the mach-ii waters again.


2. A short repetition


Let's just quickly go through what we learned/did in the first part.


  • In the mach-ii.xml config file we define a default event.
  • The default event calls a view.
  • What view file to display is defined under page-views in the mach-ii.xml file
  • The view file contained a form, which in turn defined a new event when submitted
  • This event populated a bean cfc with the values posted from the form
  • This event also notified a listener, which in turn passed the bean as an argument to a CRUD cfc.


Now do you remember the assignment I gave you at the end of part 1?

Without any further ado, here's the solution:


<event-handler event="message.create" access="public">


                        <event-bean name="message" type="MyGuestbook.model.message.message" /> 

                        <notify listener="messageListener" method="createMessage" />

                        <view-page name="mainTemplate" />



I'm pretty sure that you had that one figured out yourself.





3. Where do we go from here?


The obvious first thing to do is to get the submitted messages displayed on our page. So we need to query the database for inserted messages, and find the mach-ii way of getting the output displayed on our display page.


In the first part we used a CRUD cfc for putting a message into the database. But I also said that a CRUD should only deal with one record in the database at a time. So for queries retrieving multiple records we need to create another cfc, a so called gateway.


We write the following code, and save it as messageGateway.cfc in our model/message/ directory.


<cfcomponent displayname="Message Gateway" hint="I am a data gateway to messages">


            <cffunction name="init" access="public"             returntype="MyGuestbook.model.message.messageGateway" output="false">

                        <cfargument name="dsn" type="string" required="true" />          

                        <cfset variables.dsn = arguments.dsn />

                        <cfreturn this />



            <cffunction name="findMessages" access="public" returntype="query" output="false">

                        <cfset var findMessages = 0 />

                        <cfquery name="findMessages" datasource="#variables.dsn#">

                                   SELECT *

                                   FROM guestbook

                                   ORDER BY id


                        <cfreturn findMessages />





So we started out with the familiar part this time. The init method we remember from the CRUD (go back and read part 1 if you're insecure about it - I know I did).  Then the findMessage method is a good ole' SELECT * query.


Seeing that the init method here is the same as in the CRUD is a pretty good clue that the gateway also is called from a listener. So now we're going to do the same. In fact we'll do it in the same listener. So let's open up the messageListener.cfc and modify it as so:




<cfcomponent extends="MachII.framework.Listener" displayname="Message Listener" hint="I am the listener for messages">


<cffunction name="configure" access="public" returntype="void" output="true" displayname="Listener Constructor"

   hint="I initialize this listener as part of the framework startup.">


var dsn = getAppManager().getPropertyManager().getProperty("dsn");

variables.messageCRUD = CreateObject("component", "MyGuestbook.model.message.messageCRUD").init(dsn, "MyGuestbook");

variables.messageGateway = CreateObject("component", "MyGuestbook.model.message.messageGateway").init(dsn, "MyGuestbook");





<cffunction name="createMessage" access="public" returntype="void" output="false" displayname="Create Message" hint="I cause message to be created from the current event object.">

<cfargument name="event" type="MachII.framework.Event" required="yes" displayname="Event" hint="I am the current event" />

<cfset var message = arguments.event.getArg("message") />

<cfset variables.messageCRUD.create(message) />



<cffunction name="getAllMessages" access="public" returntype="query" output="false" displayname="Get All Messages" hint="I return a query containing all of the messages.">

            <cfreturn variables.messageGateway.findMessages

About This Tutorial
Author: Trond Ulseth
Skill Level: Intermediate 
Platforms Tested: CFMX
Total Views: 117,553
Submission Date: March 31, 2005
Last Update Date: June 05, 2009
All Tutorials By This Autor: 1
Discuss This Tutorial
  • Very good material Trond - and it's certainly helping a lot of things drop into place that were sort of already there but not clarified. I think the little bugs have been pointed out previously (I wish I knew as I struggled to solve them myself but maybe I learned more that way anyhow :) ?) A couple of small comments that I hope will be constructive, and I may be worng as I'm still trying to learn as well - for those people using different databases it may be worth abstracting the dao bits and have an example showing your default and then letting people write their own as an exercise (I used MS Access and had to rewrite becuase of the specialised treatement of the "date" fieldname - [date]) - for the edit and delete links, rather than hardcode index.cfm?event= ... it may be possible to use the same type of technique as fuseboxers and have a request.self and/or request.myself variable - I'm just not sure how to do it correctly in mach-ii - perhaps it should come from a ... getPropertyManager.getProperty("myself") type request. Anyway - keep up hte good work - I'm really looking forward to the third tutorial. Cheers

  • I went to the conference in Vegas when mach-ii was first released. This tutorial is the first time I've actually understood any of it. Learnt heaps about cfc's and fieldsets (?). Found the edit / update and id errors, but worked that out myself. That alone helped me to sus out the debugging side of things. Thanks for taking the time to pen the tut...

  • Ok the stupid title is inspired by the fact that the Hitch Hikers Guide to the Galaxy is about to premiere. If you have not read the book the title of this comment probably looks extremly stupid. Well, well. Oguz - I really aprechiate all feedback pointing out mistakes I've made. And even more suggestions to improve my code. I'll be sure to bring the announce event with me as I venture into writing part 3. Matt - I saw you asking the same question on the mach-ii email list. Sean provided the answer (for you not on the list: Cara - The JS works fine with me. Maybe you try and download the source code I have to see if that one works (if so it's something wrong with your code - if not there's something with my code in combination with your browser). You can find the download at

  • Hi I really liked you tutorial. The only part thet I can't get is the script that closes the edit window. After submitting the page doesn't seem to be preforming the following code.

  • first of all. thanks for writing parts i and ii of this tutorial. i've been scrapping around for mach ii tutes and yours def. has helped me learn quite a bit over the last 2 days. very much appreciated. i just had a quick question that i can't seem to get by. when i update content it calls editTemplate. but when i do that i get a js alert saying that this form already contains post data. so i click 'ok' and my original entry and the updated one remain. do you know what might be happening? thanks again for the tutorial. looking forward to part 3.

  • Thanks for this great effort! I hope we will have some more documentation about Mach-II.

  • After creating a record, instead of getting all records, you can announce "showMain" event with following code.

  • There is no hidden ID. Ok but hidden ID code must be like Or there would be line like that on form.

  • must be

  • You are right Young Kim, I've got the hidden input in my code, but somehow it did not make it into the tutorial. And you are just as right about the update/edit mix up - I see now that I am not consitent on which word to use. Thank you for pointing this out. I'll be sure to make the correction in my files. I plan to post corrected pdf versions of the tutorials on my website. Glad you enjoyed it despite the ugly mistakes. Trond


Sponsored By...
Mobile App Development (IOS, Android, Cordova, Phonegap, Objective-C, Java) - Austin, Texas Mobile Apps - Touch512, LLC.