yeomanly

So you want to create a CFWheels application? ( Part 3 )

2009 July 30
tags: CFWheels · ColdFusion
by Mike Henke

This CFWheels series is heavily borrowed from Dan Wilson's "So You Want to" series about Model Glue:Unity.  This entry matches to this post.

Previously in this series, we installed CFWheels, discussed some basic conventions over configuration and concepts in CFWheels, and added our basic flow and navigation. Our Contact-O-Matic is moving right along (this last sentence was borrowed from Dan's post.)

In this segment of our regularly scheduled programming (again borrowed), we will setup a Contactomatic database with tables, add the contact form, and contact list.

Database Setup

CFWheels 0.9.3 supports SQL Server 7 or later, Oracle 10g or later, PostgreSQL, and MySQL 5. You will need to setup a database and a simple table. Here is my code for MySQL 5. Please post your creation code in the comments if you are using a different database system.

DROP TABLE IF EXISTS 'contactomatic'.'contacts';CREATE TABLE 'contactomatic'.'contacts' ( 'id' int(10) unsigned NOT NULL AUTO_INCREMENT, 'name' varchar(45) NOT NULL, 'type' varchar(45) NOT NULL, PRIMARY KEY ('id')) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1;

Add a datasource called "contactomatic" to our new database through the ColdFusion Administrator

Config

CFWheels simplifies alot of time consuming steps we have gotten use to in developing ColdFusion application using conventions (or assumptions) of our database and naming.  Don't worry, we can override these assumptions/conventions if needed.

Our first convention we encounter in CFWheels assumes our datasource name is the same as the webroot folder name. We will override that in config/development/settings.cfm . Place this code in that file.

<cfset set(dataSourceName="contactomatic")>

More on configuration and defaults.

Environment

We will make sure our CFWheels environment is pointing to development. Check the enviroment.cfm file in the config folder has this.

<cfset set(environment="development")>

More on switching environments.

Model

The Model folder is where we will create cfc files that map to tables. One cfc per table. Since we created a contact table, we will create a contact.cfc and place this code in it:

<cfcomponent extends="Model" output="false"></cfcomponent>

New Action

We will add the new action in our contact.cfc file in the controller. Add this code to in the Controllers/contact.cfc .

<cffunction name="new"><cfset newContact = model("contact").new() /><cfset newContact.name = "Mike Henke" /><cfset newContact.type = "Friend" /><cfset newContact.save() /><cfset renderNothing() /></cffunction>

And run the page, remember your URL maybe different depending on your URL Rewriting setting.

URL Rewriting On = http://localhost/contact/new

URL Rewriting Partial = http://localhost/index.cfm/contact/new

URL Rewriting Off = http://localhost/index.cfm?controller=contact&action=new

You should see nothing in the browser but check our contacts table.

select * from contacts

Pretty neat, look mamma no SQL!!! What we did was create an object called newContact to represent our Contact table, then added properties that map to our columns.

Create View

Lets drive on and create the new view page.  It will have a form to add new contacts, but before we do that let's modify the new action by commenting out this code.

<!--- <cfset newContact.name = "Mike Henke" /> <cfset newContact.type = "Friend" /> <cfset newContact.save() /> <cfset renderNothing() /> --->

Now lets add new.cfm in the Views folder and place this code in it.

<cfoutput>#includePartial("banner")#<p><cfoutput>#flash("success")#</cfoutput></p>#startFormTag(action="create")#<div>#textField(objectName="newContact", property="name", label="Contact")#</div><div>#textField(objectName="newContact", property="type", label="Type")#</div><div>#submitTag()#</div>#endFormTag()#</cfoutput>

You may remember the includePartial from Part 2. It acts a cfinclude with special powers. We added our banner for navigation this way. The rest of the code looks like ColdFusion functions. They are actually CFWheels Helpers. startFormTag() starts the form tag with an action of create. Pretty intuitive, huh. Take a guess on what textField() does.

Bingo. It creates a text field. You can figure out the rest hopefully :-)

textField() takes the blank newContact object we created in new action and matches the property (column name) and gives it a label.

Run the page and you should see this.

URL Rewriting On = http://localhost/contact/newURL Rewriting Partial = http://localhost/index.cfm/contact/newURL Rewriting Off = http://localhost/index.cfm?controller=contact&action=new

Adding Create Action

Lets add the create action in controllers/contact.cfc .

Add this code:

<cfoutput>#includePartial("banner")#<p><cfoutput>#flash("success")#</cfoutput></p>#startFormTag(action="create")#<div>#textField(objectName="newContact", property="name", label="Contact")#</div><div>#textField(objectName="newContact", property="type", label="Type")#</div><div>#submitTag()#</div>#endFormTag()#</cfoutput>

Enter some data into our form and submit it.

Delete <cfset redirectTo(action="new")> and uncomment <cfset redirectTo(action="list")> in our create action.

List

Lets create our list action and view, then take a break and get a drink. We will go more indepth what we did in the next posts.

Add this code in controllers/contract.cfc, it creates the sql and get a list of our contacts.

<cffunction name="list"><cfset allContacts = model("contact").findAll() /></cffunction>

Add list.cfm in the views/contact folder with this code:

<cfoutput>#includePartial("banner")#<p><cfoutput>#flash("success")#</cfoutput></p><cfif allContacts.recordcount EQ 0 >-No Saved Contacts-<br /><cfelse><table><tr><th>Name</th><th>Type</th></tr><cfloop query="allContacts"><tr><td>#allContacts.name#</td><td>#allContacts.type#</td></tr></cfloop></table></cfif></cfoutput>

Add another contact and you should now see something like this.

By now, you should have an appreciation for what CFWheels can do. You should be very impressed by the power of built in ORM and Conventions over Configuration. You should be proud of yourself for making it through these verbose tutorials. In the following series, we will add database access, some ajax and some other interesting pieces to our Contact-O-Matic (again this paragraph was borrowed heavy from Dan's post)

So you want to create a CFWheels application? ( Part 3 )

15 Responses leave one →
  1. Chris Peters
    Jul 30, 2009 at 9:41 PM

    Nice write-up, Mike! This does a good job of capturing the essence of what you can do rapidly with Wheels. Looking forward to reading the rest of the series.

  1. Raul Riera
    Jul 30, 2009 at 9:57 PM

    Pretty nice, you can spoil them and just Scaffold the table, that would really speed things up :D

  1. Chris Peters
    Jul 31, 2009 at 6:42 AM

    Hey, people need to know what they're really doing before they use your fancy toys, Raul. ;)

  1. Mike Henke
    Aug 1, 2009 at 7:05 AM

    Thanks guys. @Raul I'll probably show the Scaffolding tool when I cover plugins maybe part 7.

  1. Saul
    Saul PERMALINK
    Sep 10, 2009 at 9:37 AM

    I lost you at "Adding Create Action
    Lets add the create action in controllers/contact.cfc ." then you use the same cfoutput code previously used in new.cfm

    Presumably in contact.cfc it should be some <cffunction name="new"> rather than output?

  1. Mike Henke
    Sep 10, 2009 at 9:47 AM

    Thanks Saul, some reason editing this post is a pain :-) here is the actual code

    <cffunction name= "new">
       <cfset newContact = model("contact").new() />
       <cfset newContact.name = "Mike Henke" />
       <cfset newContact.type = "Friend" />
       <cfset newContact.save() />
       <cfset renderNothing() />
    </cffunction>

  1. Saul
    Saul PERMALINK
    Sep 10, 2009 at 9:56 AM

    Sorry, completely losing my marbles now, it's the "create" function I'm missing I think Mike.

  1. Mike Henke
    Sep 10, 2009 at 10:04 AM

    I understand :-) Looks like that code is wrong also. I probably need to bite the bullet and re-correct this post.

    <cffunction name="create">
    <cfset model("Contact").create(params.newContact)>
    <cfset flashInsert(success="User #params.newContact.name# created successfully.")>
    <cfset redirectTo(action="new")>
    <!--- <cfset redirectTo(action="list")> --->
    </cffunction>

  1. Brian
    Oct 26, 2009 at 6:38 PM

    Yes Mike - please correct the "Add this code" example under the "Adding Create Action" header as I TOTALLY got lost until I saw the comments at the bottom.

    I know I'm not going to be the last.

    A great write-up! Thanks for your work on this!!!

  1. Daniel
    Daniel PERMALINK
    Jan 21, 2010 at 12:20 PM

    I would like to mention that case really matters. If the Contact.cfc files in the controllers and models folders doesn't have the first letter uppercase, then you will get some errors which will give a beginner (like myself) a really frustrating time trying to follow this tutorial.

  1. Mike
    Jan 21, 2010 at 12:29 PM

    Daniel - Are you running on Windows, Mac, or Linux?

  1. Daniel
    Daniel PERMALINK
    Jan 21, 2010 at 12:35 PM

    I am running on a Mac, but I have my Cold Fusion server setup on a local virtual machine that's running on Debian Linux. I've got Eclipse setup to copy the files I save to a samba share from that Linux virtual machine.
    Now that you bring it up, I remember that you can get away with all lowercase in Windows... but Linux isn't so forgiving. I believe from the little bit that I read on the cfwheels documentation page that the convention is to keep the first letter uppercase on the file names of the cfc's.

  1. Mike Henke
    Jan 21, 2010 at 12:41 PM

    Sounds like you figured it out. Linux being case sensitive and Wheels does favor Conventions over Configuration so you should try to follow the conventions. Are you in the http://groups.google.com/group/cfwheels it is a great place for questions? And Welcome to Wheels :-)

  1. Daniel
    Daniel PERMALINK
    Feb 26, 2010 at 12:26 PM

    Ok, so it was really bothering me that the code is incorrect on this tutorial so here's what I think it should be for the create action in the contact controller.
    <code><br />
    <span class="cc_cftag">&lt;cffunction</span> name=<span class="cc_value">"create"</span><span class="cc_cftag">&gt;</span><br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cc_cftag">&lt;cfset</span> newContact = model(<span class="cc_value">"contact"</span>).new(params.newContact) <span class="cc_cftag">/&gt;</span><br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cc_cftag">&lt;cfset</span> newContact.save() <span class="cc_cftag">/&gt;</span><br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cc_cftag">&lt;cfset</span> redirectTo(action=<span class="cc_value">"list"</span>) <span class="cc_cftag">/&gt;</span><br />
    <span class="cc_cftag">&lt;/cffunction&gt;</span><br />
    </code>

  1. Brad
    Brad PERMALINK
    Jun 26, 2010 at 3:44 AM

    Mike,

    The create action in controllers/contact.cfc is still incorrect. I saw your correction in the comments. You may want to update that. thanks again!

Leave a Reply

Leave this field empty: