Recently my good friend and colleague Mike Klostermeyer - who everyone would recognize as a brilliant programmer and guru if he would just learn to blog - suggested that I include some simpler posts among my obscure troubleshooting play-by-plays. Here's one that most CF programmers have had to overcome at some point. Now before we go on I have to point out that there are 4 or 5 ways to do this - not counting things like Hibernate and the "black box" stuff that ships with many frameworks. What I'm illustrating here is the capabilities of the language. Moreover, if you have to support any legacy code (as 95% of us do) then you don't always have other options. You have to find a solution that works in context. With that in mind let's proceed.
Our problem stems from a typical form you might create as a part of an admin toolkit. Let's suppose you select multiple records from the database and load them into the form. When you submit the form you want all the values of the form fields to "update" the values in the table. Simple right? To start with we have 2 assumptions:
Now let's say we have the following data from the table "famousLargeMouths":
ID | FirstName | LastName |
---|---|---|
1 | Mick | Jagger |
1 | Angelina | Jolie |
Now a beginning programmer might do something like this:
ID: | firstname: | lastname: |
ID: | firstname: | lastname: |
Submitting such a form would give you the following output:
struct | |
---|---|
FIRSTNAME | Mick,Angelina |
ID | 1,2 |
LASTNAME | Jagger,Jolie |
ID: | firstname: | lastname: |
ID: | firstname: | lastname: |
ID: | firstname: | lastname: |
Perhaps you see the problem right away. Robert Downey, Jr. has a comma in his name (We probably don't "need" the comma, but let's just say...). That means when we submit the results are going to look like this:
struct | |
---|---|
FIRSTNAME | Mick,Angelina,Robert |
ID | 1,2,3 |
LASTNAME | Jagger,Jolie,Downey, Jr. |
Anyone? Bueller? The addition of the comma after "Downey" means the list length for "lastname" is now 4 and not 3. The code we have created is going to truncate Mr. Downey's name (though not of course his ego). We could add some JavaScript to tease out commas and replace them with pipe symbols before submission and then add a replace function to put them back in for our update query. That would work I suppose, but I suggest that we get away from the this listGetAt() approach altogether. It seems error prone.
Here's my approach to this simple problem. Note, as I said before this is just one way to solve this issue. The point here is to get you thinking and add another arrow to your CF quiver. My approach would be to use independent form names. Instead of trusting a single form name and field to carry all the data for a database column, I'm going to create separate names that represent the "cell" (both the row and the column). Here's my new sample code:
Now, when I submit my form the form values look like this:
struct | |
---|---|
allIds | 1,2,3 |
Firstname_1 | Mick |
Firstname_2 | Angelina |
Firstname_3 | Robert |
Lastname_1 | Jagger |
Lastname_2 | Jolie |
lastName_3 | Downey, Jr. |
I've managed to encapsulate each value in its own form field which makes the use of commas a non issue. Now all I need to do is loop through it and update like so:
This keeps me from various search and replace expressions. It also kind of reflects more clearly the "Row and column" organization of a table in the DB - so I personally find it easier to understand from the outset.
Ok, Muse readers, I know you have your keyboard at the ready. Let's hear how you solve this particular problem and why you think it's a better approach. I look forward to comments as always.