So you want to create a CFWheels application? (Part 5)
Published on
This CFWheels series is heavy borrowed from Dan Wilson's "So You Want to" series about Model Glue:Unity and matches to this post Previously in this series, we installed CFWheels, discussed some concepts in CFWheels, added our basic flow and navigation, created add and list functionality, and validation to our Contact-O-Matic Application. Next in the series, we will cover the built in ORM of CFWheels. An Object Relation Mapper (ORM) is used to translate between our Relational Database and our Object Oriented programming. One nice thing, it is simplifies common sql statements thus saving us time and reducing sql errors. More complex SQL will still need to be coded. Don't think you won't have to learn SQL, the ORM can't do everything better but it will make the mundane tasks simplier.
CFWheel ORM
I glossed over some important convention before in our series. CFWheels expects the table name to be plural like contacts, a primary keys in the tables, and the primary key column to be name id. Our Contacts table meets all these. We can override the table name and primary key column name but CFWheels does need a primary key.
Database Code
Lets drop our old table and create it along with a types table using this code.
DROP TABLE IF EXISTS contactomatic.contacts;
CREATE TABLE 'contactomatic'.'contacts' ( 'id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'name' VARCHAR(<span class="cc_numeric">45) NOT NULL, 'typeid' INTEGER UNSIGNED NOT NULL, PRIMARY KEY ('id') ) ENGINE = InnoDB;
DROP TABLE IF EXISTS contactomatic.tbl_typesofcontact; CREATE TABLE 'contactomatic'.'tbl_typesofcontact' ( 'typeid' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'title_for_type_of_contact' VARCHAR(<span class="cc_numeric">45) NOT NULL, PRIMARY KEY ('typeid') ) ENGINE = InnoDB;
INSERT INTO contactomatic.tbl_typesofcontact (title_for_type_of_contact) VALUES('Friend');
INSERT INTO contactomatic.tbl_typesofcontact (title_for_type_of_contact) VALUES('Enemy');
INSERT INTO contactomatic.tbl_typesofcontact (title_for_type_of_contact) VALUES('Co-Worker');
Types Model
In our /controller/contact.cfc add this code to the
new
<cfset types = model("type").findAll() />
<cfset allContacts = model("contact").findAll(include="type") />
<cfdump var="#allContacts#"><cfabort>
URL Rewriting On = http://localhost/contact/new?reload=true
URL Rewriting Partial = http://localhost/index.cfm/contact/new?reload=true
URL Rewriting Off = http://localhost/index.cfm?controller=contact&action=new

Table Naming
Well, you can see CFWheels assumes we have a types table since our newly created model cfc's name is type. Our table's name is actually tbl_typesofcontact, we could rename the cfc to tbl_typesofcontact.cfc, but CFWheels convention also says our table name should be plural. Lets tell (configure) CFWheels we already have a table name that doesn't fit in CFWheel's conventions. Add this code to our type.cfc in the models folder.
<cffunction name="init">
<cfset table("tbl_typesofcontact") />
<cfset property(name="title", column="title_for_type_of_contact") />
</cffunction>

<cfset types = model("type").findAll() />
new
Select Helper
Lets add our select box populated from this query to our form using a CFWheels helper. Replace in /view/new.cfm
<span class="cc_normaltag"><div>#textField(objectName="newContact", property="type", label="Type")#<span class="cc_normaltag"></div>
<span class="cc_normaltag"><div>#select(objectName="newContact", property="typeid", options=types, label="Type", includeBlank="")#<span class="cc_normaltag"></div>

<cfcomponent extends="Model" output="false">
<cffunction name="init">
<cfset validatesPresenceOf(property="name",message="Name is Required") />
<cfset validatesPresenceOf(property="typeid",message="Type of Contact is Required") />
<cfset validatesUniquenessOf(property="name", message="Name is already present") />
<cfset belongsTo(name="type", foreignKey="typeid")>
</cffunction>
</cfcomponent>
<cfset belongTo("type")>

Association
Here is where our association we set in /models/contact.cfc comes to play. CFWheels ORM joins the tbl_typesofcontact table with the contacts table. This happens because we added the association declaring the foriegn key in our /models/contacts.cfc and in creating the query, we told it to include type.
<cfset allContacts = model("contact").findAll(include="type") />
<cfdump var="#allContacts#"><cfabort>
URL Rewriting On = http://localhost/contact/list?reload=true
URL Rewriting Partial = http://localhost/index.cfm/contact/list?reload=true
URL Rewriting Off = http://localhost/index.cfm?controller=contact&action=list&reload=true
