CFWheels - Pragmatic, Beautiful Code

Preview:

DESCRIPTION

This is my presentation about CFWheels at CFObjective ANZ, November 2010, Melbourne, Australia. ColdFusion on Wheels (CFWheels), is an elegant framework inspired by Ruby on Rails.

Citation preview

CFWheels Pragmatic, Beautiful code

Indy Nagpal Straker Software Melbourne, November 2010

A bit about me

•  CTO, Straker Software, New Zealand

•  Been doing CF (and Flex) for a while

•  Cloud-based CF Using Railo

•  In love with Ruby (the language) & Rails

– Was in love with Groovy (still am, I think)

•  nagpals.com/blog

Rapid ≠ Agile

Agile

•  Early, continuous delivery of software

•  Welcome changing requirements

•  Deliver working software frequently

•  Working software = progress

•  Technical excellence and good design

•  Simplicity is essential – work not done

“There comes a time in the history of every project when it becomes

necessary to shoot the engineers and begin production.”

Need

•  Quickly build and deploy database-driven web apps

•  Rapid iterations in a testable fashion

•  Easy for multiple developers to understand

•  Working app is more important than configuring the app

Search…

•  Tried lots of frameworks/methodologies

•  Ruby on Rails addressed most issues

•  Learn another language and framework

•  Defeats the whole purpose

•  Enter, CFWheels…

What is CFWheels

•  Framework inspired by Ruby on Rails

•  Simple organization system

•  Suited for typical, database-driven web applications

•  A couple of years’ old – fairly mature

Convention over configuration

•  Possibly the single most important thing

•  Mostly convention, minor configuration

•  Easy to

–  turn on

–  tune in

– drop out

Directory structure •  webroot – models– controllers– views

– images– javascripts– stylesheets

– plugins

– tests– events– config

Intuitive Code Structure •  View

–  Responsible for display and user interaction –  Receive data from controller

•  Controller –  Process requests from view –  Get/process data from model –  Make data available to the view

•  Model –  Interacts with the database layer –  Responsible for validation –  Other methods to process/message data

Convention - URLs

•  URLs mapped to controllers/models/views

http://blog/posts/edit/1Controller: Posts

Model: Post

Action: Edit

Key: 1

View – http://blog/posts/ /views/posts/index.cfm

<cfparam name="posts"><ul><cfoutput query="posts"><li> #linkTo( text = "#posts.title#", action= "edit", key = post.id, title = "Edit #posts.name#" )#</li>

</cfoutput></ul>

Controller – http://blog/posts/ /controllers/Posts.cfc

<cfcomponent extends="Controller"><cfscript>function index(){ posts = model("post").findAll(order="createdAt")}

</cfscript></cfcomponent

Model – http://blog/posts/ /models/Post.cfc

<cfcomponent extends="Model"><cfscript>function init(){ belongsTo("author") hasMany("comments") validatesLengthOf( properties = "title", minimum = 10, maximum = 255)}

</cfscript></cfcomponent>

Convention – Files & Database

•  Place in appropriate folders – MVC

•  Plural database names, singular model names

– DB Table: posts– Model: Post.cfc

•  Database fields: id, createdat, updatedat

Built-in ORM

•  Simple and elegant

•  All major databases supported

•  Almost no setup required – baked in

•  CRUD instantly available via models/plugin

•  Finding data using “finders” –  findOne(), findAll(), findByKey()…

Associations models/Post.cfc

<cfcomponent extends="Model"> <cfscript>

function init(){ belongsTo("author") }

</cfscript> </cfcomponent>

models/Author.cfc

<cfcomponent extends="Model"> <cfscript>

function init(){ hasMany("posts") }

</cfscript> </cfcomponent>

<cfscript>posts = model("post").findAll(include="author")author = model("author").findOneByKey(key=params.key,include="posts")

</cfscript>

Dynamic Finders

•  Dynamic finders are magical model("user").findOne(where="username='bob' and password='pass'")

rewritten as

model("user").findOneByUsernameAndPassword("bob,pass”)

URLs and Routing

•  Beautiful URLs –  http://blog/a-good-url

•  Powerful routing mechanism <cfset addRoute( name = "showPost",

pattern = "/[key]”, controller = "Posts", action = "show")>

•  Can be turned REST-full

Multiple response formats •  http://blog/posts

•  http://blog/posts.xml

•  http://blog/posts.json

•  http://blog/posts.csv

•  http://blog/posts.pdf

Common tasks done

•  Adding timestamps

•  Flashing messages

•  Pagination

•  Sending multi-part emails

•  Redirecting users

Lots of helper functions •  Views

selectBox()

linkTo()

timeAgoInWords()paginationLinks()

titleize()pluralize()

•  Model validatePresenceOf()

findAll()

findOneByKey()afterSave()

•  Controller flash()

isGet()sendMail()

Plugins

•  Neat architecture to add/override functionality

•  Extremely useful

– Scaffold –generate CRUD application

– DBMigrate – Add/edit database structure

– Remote Form Helpers – Ajax with forms

– Localizer – Localizing an application

Baked in testing

•  Ships with RocketUnit <cfcomponent extends="tests.Test"><cfscript>

function test_1_get_timezones(){ qTimezone = model("Timezone").getTimezones() assert("isQuery(qTimezone) ") assert("qTimezone.recordcount eq 56")}

</cfscript></cfcomponent>

Environments

•  Different setup for applications based on stages of development

– Design, Development, Production, Testing, Maintenance

•  Differ in terms of caching, error-handling

•  Switch environments via config/url

Docs/Support

•  Very helpful docs at cfwheels.org

•  Active and supportive mailing list

•  Quite a few screencasts

•  Direct knowledge transfer from Ruby on Rails books/docs (e.g., Head First Rails)

•  Bunch of blogs

IDE Support

•  Eclipse, CFBuilder

– Syntax Dictionary

•  Textmate

– Bundle

•  Coda

– Lacking, but works by adding Clips

Beauty

•  Simple code organization and flow

•  Easy to understand code – eyeballing code

•  Common tasks done with minimal code

•  Pretty URLs

•  Almost zero configuration, with power to configure as much as needed

Pragmatic

•  Focus on simple code that solves issues

•  Trades pure OO for simplicity and structure

•  Easy to not use the framework if needed

•  Common web application problems already solved – why reinvent the wheel(s)!

Wrap up

•  Evaluate if you need a ‘framework’

•  Learn URL rewrites (Apache, IIS)

•  Dabble with Ruby on Rails

•  cfscript = succinct code

•  Worth trying out just to see how problems can be solved in a different manner

Thank you

Questions?

indy@nagpals.comnagpals.com/blog