Much thanks to Nando and Mark on this - I added the queryRowToStruct method
to a UDF component rather than inside the DAO and I'm calling it like this:

        guideQuery = gateWayObject.selectGuideByID(url.gu_id);
        udfObject = createObject("component","guideUDFs").init();
        guideObject =
createObject("component","guide").init(argumentCollection=udfObject.queryRow
ToStruct(guideQuery));

which works great - the only problem I had was that when I built the guide
bean I didn't use the exact same column names as the database (my db columns
all have a gu_ prefix which I didn't bother to use in the bean).  I was
purposely trying to make it so that the bean wasn't tied specifically to the
table (which it definitely is).  It's not really a problem, I just had to
select each column individually with an alias rather than use select * for
the query.  I guess this would be the kind of thing a "data mapper" would
handle (but I don't think I'm ready for that yet).

Thanks again - my guide is still a bit lost but at least he has flashlight.

Kirk


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Nando
Sent: Wednesday, January 19, 2005 7:38 PM
To: [email protected]
Subject: RE: [CFCDev] Using queries to populate an object


Kirk,

Here's a suggestion ...


<cfcomponent displayName="GuideDAO" hint="" output="false">

        <cffunction name="init" access="public" returntype="thePath.GuideDAO"
output="false">
                <cfargument name="Guide" type="thePath.Guide" required="Yes" />
                <cfset variables.Guide = arguments.Guide />
                ... DSN stuff
                <cfreturn this />
        </cffunction>

.....

        <cffunction name="read" access="public" returntype="VOID" 
output="false">
                <cfargument name="uniqueRecordID" type="numeric" required="yes" 
/>

                <cfset var qRead = "" />

                <cfquery name="qRead" datasource="#variables.dsn#">
                        SELECT *
                        FROM tblGuide
                        WHERE idGuide = <cfqueryparam cfsqltype="cf_sql_integer"
value="#arguments.uniqueRecordID#" />
                </cfquery>

                <cfif qRead.RecordCount GT 0>
                        <cfset 
variables.Guide.setInstanceFromStruct(queryRowToStruct(qRead)) />
                </cfif>
        </cffunction>

 .....
        (this is available also as a UDF on cflib.org - structs are easier to 
pass
around than query rows ... )
        <cffunction name="queryRowToStruct" access="private" returntype="struct"
                        hint="I return a structure from a queryRow passed into 
me."
output="false">
                <cfargument name="query" required="Yes" type="query" />
                <cfargument name="row" type="numeric" default="1" />
                <cfset var ii=1 />
                <cfset var cols = listToArray(query.columnList) />
                <cfset var structReturn = StructNew() />

                <cfscript>
                        for(ii = 1; ii lte arraylen(cols); ii = ii + 1){
                                structReturn[cols[ii]] = 
query[cols[ii]][arguments.row];
                        }
                </cfscript>

                <cfreturn structReturn />
        </cffunction>
</cfcomponent>

<cfcomponent displayName="Guide" hint="I'm a little lost, but gimme time,
I'll get there." output="false">

        .....

        <cffunction name="getInstanceAsStruct" access="public" 
returntype="struct"
output="false">
                <cfset var returnData = StructNew() />
                <cfset returnData.guideName = getGuideName() />
                <cfset returnData.guideAddress = getGuideAddress() />
                <cfreturn returnData />
        </cffunction>

        <cffunction name="setInstanceFromStruct" access="public" returntype=""
output="false">
                <cfargument name="data" required="true" type="struct" hint="The 
struct
containing the data to set." />
                <cfscript>

                        if(structKeyExists(data,"guideName")){
                                setGuideName(data.guideName);
                                }
                        if(structKeyExists(data,"guideAddress")){
                                setGuideAddress(data.guideAddress);
                                }

                </cfscript>
                <cfreturn this />
        </cffunction>

        .....
</cfcomponent>


<cfset session.Guide = CreateObject(
                'component','thePath.Guide').init() />
<cfset createObject('component','thePath.GuideDAO').init(
                                session.Guide).read(uniqueRecordID) />
<cfset structOfFormValues = session.Guide.getInstanceAsStruct() />

Use the structOfGuideValues to populate your form, eg:

<input type="text" name="guideName" value="#structOfFormValues.guideName#">

Take a close look ... you can use exactly the same mechanism to populate
your new record form

The thing that's really useful here is that you can use Guide to validate
and hold data for the form. On submit, use setInstanceFromStruct(), validate
your data, and if something doesn't validate, your all set to repopulate the
form with

<cfset structOfFormValues = session.Guide.getInstanceAsStruct() />

if it does validate, your all set to save the instance with your DAO, using
getInstanceAsStruct()

<cffunction name="update" access="public" returntype="VOID" output="false">

        <cfset var instance =  "" />
        <cfset var qUpdate = "" />
        <cfset instance = variables.Guide.getInstanceAsStruct() />

        <cfquery name="qUpdate" datasource="#variables.dsn#">
                UPDATE tblGuide SET
                guideName = <cfqueryparam cfsqltype="cf_sql_varchar"
value="#trim(instance.guideName)#" />
                ...

Hope that helps. It took me some time in the beginning to work that all out
from scratch. But it seems to work very well.
Nando :)

PS ... Some more stringent about their OO might use the getters instead of
the getInstanceAsStruct() ...

guideName = <cfqueryparam cfsqltype="cf_sql_varchar"
value="#variables.Guide.getGuideName()#" />

I found the getInstanceAsStruct() a little cleaner in the beginning ... you
could do it either way.

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Kirk Brogdon
Sent: Thursday, January 20, 2005 2:53 AM
To: [email protected]
Subject: [CFCDev] Using queries to populate an object


I'm trying to figure out how (or if I should) use a query to instantiate an
object.  I have a guide.cfc bean that works great as far as creating a new
record by passing the (argumentcollection=form) to the init function from
form data.  How would I do this in reverse so that I can edit data that has
already been stored?  I have a lookup form that returns query data and
displays the results so the user can then select from those results which
will pass the unique record id to another query method that returns the
specific result set (which all works ok).  So now I have a query with
everything I need to populate a form for editing but I'm not sure what to do
with it from an OO/cfc viewpoint - should I just populate a form directly
from that query and then after they have made their changes, create the
guide object from the form data and pass it to an update method in my DAO or
should I create the guide object from the query, populate the form with the
getters and use the setter methods to make any changes before passing to the
DAO?  Do I need to create a structure from the query and pass the structure
as the argumentcollection to the init function?

Sorry for the scattered ramblings but I would really like to know how other
people handle this type of thing.

Thanks - Kirk


----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at
www.mail-archive.com/[email protected]



----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at
www.mail-archive.com/[email protected]

----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at 
www.mail-archive.com/[email protected]

Reply via email to