I get nauseous every time I see this question asked. I wholly believe this question exists only to start infighting amongst the development community and attract the numerous comments to the post that is assured. All the while, the poster sits back with lotion and Kelnex and smiles while the chaos unfolds around them.
I come to classify the commentors to these posts into 3 categories:
First and foremost, you have the OO purists. These are the people that use OO to the extreme. DAO, BO, IOC and any other acronym you can throw out there, they’re using it and loving it. The more abstraction and configuration, the better. They will claim that it makes developing applications faster and easy to maintain and cut down anyone that saids otherwise. If they had it there way, they would have 30 different classes per business object each containing one method. Their mortal enemy is anyone still believing and writing procedural programs.
Our next category and mortal enemy of everything OO; is the procedural programmer. They’re the ones still hanging on to the days when cfincludes and custom tags flourished in applications. Who needs CFCs when a group of functions inside a cfinclude will do just fine. Don’t tell them about design patterns or code organization, they know it all too well. If they could, they would go back in time and kill the person that mentioned cfcomponent in that one board meeting. To them OO is evil and so are the people using it.
The final category is the one that I fall into: the who gives a shit and flying fuck category. Program the way you want to program and quit telling us that we’re doing it right or wrong. We don’t want nor care how you program or the philosophy that you follow. To us, both of the other two categories need to just shut the fuck up altogether.
Ruby on Rails - All I need for the switch
December 14, 2007
For a while now I’ve been looking into Ruby on Rails (RoR) to replace ColdFusion (CF) as my primary programming language of choice. There are so many things about the framework that just dazzle me to death. I know I’m comparing a language to a framework here, but to be honest, to most people there really isn’t a difference. Plus the fact that I really haven’t found a CF framework out there that I really like nor one as feature rich as RoR.
For one, I like the idea of convention or configuration (COC). How many times have you taken over an app from someone where you’ve spent days on end trying to figure out what the hell they were doing? If you embrace COC then every app is structured the same so there is no guessing at all. I can also see how COC can speed up development amongst a group of developers since everyone has to follow the same directions.
ActiveRecord (AR) is just sexy beyond belief. I love SQL, don’t get me wrong, but I grow tired of writing the same queries day in and day out (This is why I created ICEGen). Furthermore, I’ve seen some of the SQL that others have written and makes me want to throw up. If AR can help me not write the same boring SQL while preventing others from just writing it altogether, I’m sold. Coupled with the fact that the built in validation methods are just so simple to use, why would you need further convincing?
Plugins and Gems just work. I’ve seen frameworks in ColdFusion claim that you could write or download a plugin, install it and it would just work; yeah, well it doesn’t. Half the time I’m hunting and configuring files all over the place only to expense my efforts in vain. With RoR, just a simple command line and within seconds the plugin and gem are installed and work beautifully. Sure sometimes there is a little configuration to do with them, but at least in the end the plugin works as expected.
I don’t do tests, I just don’t. I’ve tried using CFCUnit and failed since it warped my fragile little mind. Tests in Rails are dead simple. Because of this, you can’t even submit a patch to the RoR team unless you include your tests. This is all done thanks to fixtures.
Those are a few things that I just love about RoR, now let’s see what huge things it’s missing that CF has.
CFDOCUMENT - What CF developer today hasn’t used this tag. There is something just magical about wrapping the tag around your invoice written in HTML and having it pull up a PDF or Flashpaper file in the browser. No need for them to have Acrobat installed so they have to print the page to PDF, it does it all for them and it’s dead simple to use. RoR doesn’t have this. PDF::Writer sucks balls and it’s hard to use. HTMLDOC doesn’t support CSS so it’s impossible to get the page to look good. Plus Flashpaper it’s even an option.
CFIMAGE - Yeah I know we just got this tag, but before you could just download imagecfc which worked just as good in my opinion and you had your image manipulation. RoR has support for ImageMagick which, if you’ve ever used it, is a dog. It’s slow as hell and doesn’t scale worth a shit. I still to this day can’t believe that this library is the defacto amongst the open source world.
As you can see there really isn’t a lot that CF offers that RoR doesn’t already have. Hopefully the RoR team will see these shortcoming and create some plugins that address them soon. For now I’m still learning and loving RoR.
Opinion: To Use Or Not To Use Stored Procedures?
November 15, 2007
I was browsing around on Reddit today and came across an article that particular struck my interest: To Use Or Not To Use Stored Procedures?
What intrigued me was that I have been a proponent of stored procedures in the past and now avoid them like the plague. I think the switch came when I started to realize how difficult and time consuming it was to write and maintain a project using stored procedures versus a project that just use parametrized queries. I also remember how difficult it was to write dynamic sql statements within a stored procedure.
I think really the only reason I used them in the past was because CF at the time didn’t support cfqueryparam and it as the only way to protect yourself against SQL injections. Once cfqueryparam came onto the seen, it took awhile for me to adopt it in my code and actually realized the benefits. Now I could write my SQL statements within CF and still have the security of a stored procedure protecting me against SQL injections. It was a blissful time; I could really pound out projects and code and debugging an application became a snap.
There were a few still out there that still voiced the myth that using stored procedures gave you a speed boost over
parameterized queries. Those people were soon put to rest when most RDMS and ODBC drivers made it so that using either way gave you the speed benefits of caching the query plan. Now this point is mute.
Today, I silently laugh at people that still think that using stored procedures in projects as the main way to communicate with their database. By creating views, using cfqueryparam and knowing the proper ways of using the different joins available; I can mimic almost any behavior a stored procedure can do when it comes to pulling data from a database.
To me I see the stored procedure in CF going the way of CFX tags… away.
CF8 Cumulative HotFix 2 is now available
November 15, 2007
TimeZone CFC submitted to RIAForge
November 14, 2007
Today a friend of mine needed help with pulling dates out a database and converting them to the local time for his clients across the country. I immediately thought of Paul Hastings’ TimeZone CFC. I downloaded it from Paul’s site and started to play with it so I could make sure that it was exactly what my friend needed.
I’m happy to say that Paul did a fantasic job. I was so impressed by it, that I decided to clean up the code and the example page a bit. When I looked on RIAForge to see if I could submit my changes, I noticed it didn’t have a project page there. So I contacted Paul and asked if he wouldn’t mind me submitting the project there. He replied back that I could and I have submitted the project to RIAForge for approval. Once the project is approved I will upload the code there.
I should mention that I only cleaned up the timezone.cfc since I don’t have the ic4j libraries installed to test against.
Thanks Paul once again for for allowing me to upload the project.
Until the approval from RIAForge, you can download the code here.
I feel honored.
November 1, 2007
Andrea over at andreacfm, has started what I consider to be one of the coolest projects: creating custom tags out of jQuery plugins. Personally I really haven’t been a fan of the new ColdFusion tags because of the amount of javascript that is loaded when you want to use them. By using jQuery, this really isn’t a issue. Plus it’s jQuery for God’s sake!
So why do I feel so honored? Well there is actually a custom tag that was created out of my PopWindow Plugin!
CF8 Extension for Eclipse bugs
October 19, 2007
Some of the bugs I’ve found with the CF8 extensions for Eclipse:
- CFIMAGE: the resize action is spelled wrong. Currently spelled rezized.
- The “Request Interface” under “ColdFusion Java CFX Reference” throws and org.xml.sax.SAXParseException error.
I’ll continue updating the list as I find more now that I’ve officially switched over to CF8 for all my projects.
Friday Puzzle: Actually I need some help :)
October 12, 2007
UPDATE: So I feel like a complete dumb ass since thanks to Angelos
I swear I was doing what they suggested and it wasn’t working for me. Last time I code and post after a 16 programming marathon.
Does anyone out there know of a way to replace part of a string with a coldfusion variable and evaluate it? Take for instance the following code:
<cfset mystr = “tony”>
<cfset str = “this is a %%test%% to see if this %%works%% or not”>
<cfset str = rereplacenocase(str, “%%([^%%]*)%%”, “##mystr##”, “all”)>
<cfoutput>#str#</cfoutput>
What I’m trying to do is to replace all occurrences of “%%test%%” with “#mystr#” and when I output the str variable, it will replace “#mystr#” with “tony”. Right now when I out then text I get the following:
this is a #mystr# to see if this #mystr# or not
I would like to get it to output like so:
this is a tony to see if this tony or not
Anyone everyone do this?
Securing your scheduled tasks
October 10, 2007
Securing your schedule tasks is probably the last thing on your mind when you launch an application, but it’s something that you might want to consider.
Here is something that I’m running into. I’ve been moving several clients off their shared hosting plans to our VPS. Now during the time they were on the shared hosting plans, they were moved from one shared server to another. In some cases if the client was moved to a new server without us knowing, or to be fair even with us knowing, the scheduled tasks that were created for that client were never deleted from the old server.
As you can see this can cause a problem. In our case we have scheduled tasks that runs every night and send out email notifications, which something I think every developer has done sometime in their carrier. Since the scheduled tasks on the old server was pointing to the domain name, the tasks were firing twice; once on the new server and once on the old. Obviously the clients weren’t too happy about getting two emails. Now this isn’t such a big deal, but you can image the havoc this could cause if the scheduled tasks did something more, like process orders or something.
So how can we prevent this from happening? Well I came up with a way to do this and I thought that it was pretty slick. Before we start though, I will say that I put all my scheduled tasks into their own folder. For the purpose of this post, let’s just say that that folder is called scheduletasks and it’s off the webroot. Also I use the application.cfc.
The first thing to do in our half-ass security to make sure that anything accessing the directory is authorized to do so. What I did was pick a url variable, it could be anything you want, but for now let’s just use secure. So if we wanted to launch our task we would have to set the url of the task property to:
http://www.example.com/scheduletasks/mytasks.cfm?secure
Now to secure this from within application, we can use the onRequestStart method in our application.cfc. Within the onRequestStart we add the following code:
<cfif FindNoCase(”/scheduletasks”, cgi.SCRIPT_NAME) AND NOT StructKeyExists(url, “secure”)>
<cflocation url=”/” addtoken=”No”>
</cfif>
Great! now if anyone is trying to access the task from the url, they will be blocked because they most likely won’t know about the secure variable. But this isn’t going to help the problem that I was having because the old tasks that I setup would have the secure variable already in their configuration. Hmmmmm what to do.
The answer came to me just the other day, why not assign the secure variable a value that’s random for the application! The only problem was what could be random between my application? The answer was the application name itself!
A long time ago I read a post by Raymond Camden that was just the cat’s ass. In the post he used a hash of the directory name of where the application was for the application name itself. It was brilliant! Since then I’ve always used this method so I don’t have to worry about naming my applications. As such all my application names are like so in my application.cfc:
<cfset variables.appname = left(hash(GetDirectoryFromPath(GetCurrentTemplatePath())), 64)>
<cfset this.name = variables.appname>
In order to use our application name for the security of our scheduled tasks, we just have to use the application.applicationname variable. To implement, we change the url property of the schedule tasks to read:
http://www.example.com/scheduletasks/mytasks.cfm?secure=#application.applicationname#
and then change our security inside the onRequestStart method to:
<cfif FindNoCase(”/scheduletasks”, cgi.SCRIPT_NAME) AND NOT StructKeyExists(url, “secure”) and url.secure NEQ application.applicationname>
<cflocation url=”/” addtoken=”No”>
</cfif>
In conclusion here is a striped down version of our application.cfc:
<cfcomponent output=”false”>
<cfset variables.appname = left(hash(GetDirectoryFromPath(GetCurrentTemplatePath())), 64)>
<cfset this.name = variables.appname>
<cffunction name=”onApplicationStart” returnType=”boolean” output=”false”>
<cfargument name=”chapter” type=”string” default=”"
hint=”this is the chapter that we want to set as the current”>
<cfschedule action=”UPDATE”
task=”mytasks”
operation=”HTTPRequest”
url=” http://www.example.com/scheduletasks/mytasks.cfm?secure=#application.applicationname#”
startdate=”#DateFormat(now(), ‘mm/dd/yyyy’)#”
starttime=”11:00:00 PM”
interval=”daily”
resolveurl=”No”
publish=”No”>
<cfreturn true>
</cffunction>
<cffunction name=”onApplicationEnd” returnType=”void” output=”false”>
<cfargument name=”applicationScope” required=”true”>
</cffunction>
<cffunction name=”onRequestStart” returnType=”boolean” output=”false”>
<cfargument name=”thePage” type=”string” required=”true”>
<cfif FindNoCase(”/scheduletasks”, cgi.SCRIPT_NAME) AND NOT StructKeyExists(url, “secure”) and url.secure NEQ application.applicationname>
<cflocation url=”/” addtoken=”No”>
</cfif>
<cfreturn true>
</cffunction>
<cffunction name=”onRequest” returnType=”void”>
<cfargument name=”thePage” type=”string” required=”true”>
<cfinclude template=”#arguments.thePage#”>
</cffunction>
<cffunction name=”onRequestEnd” returnType=”void” output=”false”>
<cfargument name=”thePage” type=”string” required=”true”>
</cffunction>
<cffunction name=”onError” returnType=”void” output=”true”>
<cfargument name=”exception” required=”true”>
<cfargument name=”eventname” type=”string” required=”true”>
</cffunction>
<cffunction name=”onSessionStart” returnType=”void” output=”false”>
</cffunction>
<cffunction name=”onSessionEnd” returnType=”void” output=”false”>
<cfargument name=”sessionScope” type=”struct” required=”true”>
<cfargument name=”appScope” type=”struct” required=”false”>
</cffunction>
</cfcomponent>
Hopefully this will be helpful to someone and if you have a better way, I would love to hear it, so leave a comment.
CF 8 HotFix 2 wish list.
October 6, 2007
Wouldn’t it be great if Adobe could fix some of the annoying outstanding bugs in the next hotfix that we as a community really need. What would you like them to fix?
For me I really want them to fix the new array and structure syntax. I personally think it’s great that you can create an array like so:
<cfset s = [1,2,3,4] >
and structures like so:
<cfset s = {a=1, b=2, c=3, d=4}>
The problem is that you can’t combine the two like so:
<cfset s = [1,2,3,4, {a=1, b=2, c=3, d=4}] >
Please Adobe, fix this in the next hotfix!