Small update to CF9 ORM CMS Demo

This post is more than 2 years old.

It's been a few days since I posted my CF9 ORM CMS demo, but I wanted to share a small update I worked on yesterday while recovering from the beach.

If you remember, both my sections and pages had a special property. Sections have a siteDefault boolean property. There should only be one section where this is true. Pages have a isHomePage boolean property where only one page per section should be allowed to set it true.

I looked into event handling in ORM as a way to handle these two rules. Event handling, as you can guess, allows you to handle ORM based events. So for example, you can run logic before an item is deleted, after it is loaded from the database, and so on. For my demo, I was concerned about two events: postInsert and postUpdate. As you can guess, these events run after an insert and update action. So if I make a new section, for example, the postInsert will fire and I'll run my special logic. If I edit an existing section, postUpdate will fire, and I can do the check there as well. Before you can begin using event handling, you have to enable it in your ORM settings:

this.ormsettings = { dialect="MySQL", dbcreate="update", eventhandling="true" };

I then modified section.cfc like so:

component persistent="true" {

property name="id" generator="native" sqltype="integer" fieldtype="id";
property name="name" ormtype="string";
property name="sitedefault" ormtype="boolean";
property name="order" ormtype="integer";

public function postInsert() {
	
	if(not isNull(variables.sitedefault) and variables.sitedefault) {
		clearAllDefault();
	}

}	

public function postUpdate() {
	if(not isNull(variables.sitedefault) and variables.sitedefault) {
		clearAllDefault();
	}
}	

/*
* We have made this section the site default, so get all the others, and set them to false
*/
private function clearAllDefault() {
	var sections = ormExecuteQuery('from section where id != ? and sitedefault = ?',[variables.id,true]);
	var i="";
	for(i=1; i <= arrayLen(sections); i++) {
		sections[i].setSiteDefault(false);
		entitySave(sections[i]);
	}

}

}

Skipping over the properties which didn't change my from the last demo, take note of postInsert and postUpdate. Both check to see if siteDefault was set and if it was true. If so, the very badly named clearAllDefault (I really couldn't think of a better name) will be run.

I run a quick query using ormExecuteQuery to get all sections where the ID does not match the current record and siteDefault is true. In theory, that will return one record, but I let it assume there could be multiple. I looped over the results and set the siteDefault value to false. page.cfc had similar modifications:

component persistent="true" {

property name="id" generator="native" sqltype="integer" fieldtype="id";
property name="title" ormtype="string";
property name="body" ormtype="text";

property name="section" fieldType="many-to-one" cfc="section" fkcolumn="sectionidfk";
property name="template" fieldType="many-to-one" cfc="template" fkcolumn="templateidfk";

property name="isHomePage" datatype="boolean";

public string function renderMe() {
	return template.getHeader() & body & template.getFooter();
}

public function postInsert() {
	
	if(not isNull(variables.isHomePage) and variables.isHomePage) {
		clearOtherHomepage();
	}

}	

public function postUpdate() {
	if(not isNull(variables.isHomePage) and variables.isHomePage) {
		clearOtherHomepage();
	}
}	

/*
* We have made this page the home page for a section, so get the other pages in the section, and set them to false
*/
private function clearOtherHomepage() {
	var pages = ormExecuteQuery('from page where id != ? and section.id = ? and isHomePage = ?',[variables.id,variables.section.getID(),true]);
	var i="";
	for(i=1; i <= arrayLen(pages); i++) {
		pages[i].setIsHomePage(false);
		entitySave(pages[i]);
	}

}

}

Focusing on just clearOtherHomepage (again, not a great name), notice the query here is a bit more precise. It looks for pages in the same section with isHomePage set to true.

I've attached the latest rev of the CMS to the blog entry. Obviously there is a lot more to event handling, but I was surprised how easy it was to use in my application. I hope this example helps other.

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Paul Connell posted on 7/31/2009 at 1:10 PM

Still trying to get my head around ORM stuff, I can see the benefits but I think combining it with the new CFC script syntax is clouding the issue for me (I'm a bluff old <tag> traditionalist!). Keep the examples coming, I'm sure it will click at some point!

Comment 2 by Todd Rafferty posted on 7/31/2009 at 2:40 PM

@Paul: Remember everything on this page can be written via CFTAG. This is just what Ray prefers (to write via script).

Comment 3 by Raymond Camden posted on 8/2/2009 at 12:23 AM

Todd is exactly right. If you feel like the script examples are a bit much, let me know though. I'm a big believer in trying to do one thing at a time when learning new stuff, and I can see how the addition of the scripting could make things more difficult.

Comment 4 by Drew posted on 10/20/2009 at 12:23 AM

How about an ORM or Hibernate category? I see that you're tagging these useful ORM posts in just the generic Coldfusion category. At least for me, I would find it useful combing through your experiences in ORM.

Comment 5 by Raymond Camden posted on 10/20/2009 at 12:29 AM

Going forward I will. In fact, I have a question in my queue about some of the more high level thinking (less code) side of ORM. That's going out tonight or tomorrow morning.

Comment 6 by Oliver Frick posted on 12/29/2014 at 5:10 PM

Hi, i know it is a quite old post, but do you eventually still have the originally attached zip?

Comment 7 (In reply to #6) by Raymond Camden posted on 12/29/2014 at 5:31 PM

I fixed the link.

Comment 8 (In reply to #7) by Oliver Frick posted on 12/29/2014 at 10:11 PM

thanks a lot.