tags:

views:

77

answers:

3

For my lookup tables, the ones that are the same for every user in the application, I do an

Application.objectname = createobject(...).init(datasource)

in the init method, I read the table into the this scope like so:

cfquery name="this.queryname"
return this

Now, whenever I need to reference the query, I can refer to it like this:

cfselect query="Application.objectname.queryname" ...

Q: Is there anything wrong with that?

+1  A: 

Syntactically, no. However, I'm assuming that you've also included a "name" attribute to that cfselect tag, since it's required.

Joe D
Yeah, I used ellipses to connote that I was purposefully leaving some stuff out.
cf_PhillipSenn
+3  A: 

No, that would be fine. The server will keep the entire object instance in memory as part of the application scope, which will include all of its properties.

As a question of style, I would suggest making your query a private property (in the variables scope in a CFC) rather than a public one (in a CFC's this scope). Allowing an object property to be public implies that as the black box designer, you're okay with an unknown developer overwriting the value. If these are database lookup tables you're storing, I'm guessing you intend this data to be read-only. Consider the following:

<cfcomponent hint="Proxy for database lookup tables" output="false">
    <cfproperty name="variables.lookupTable1" type="query" hint="[Private] lookupTable1 query object." />
    <cfproperty name="variables.lookupTable2" type="query" hint="[Private] lookupTable2 query object." />
    <!--- Implicit initialization --->
    <cfscript>
        variables.lookupTable1 = QueryNew('');
        variables.lookupTable2 = QueryNew('');
    </cfscript>

    <!--- Active initialization --->
    <cffunction name="init" returntype="void" access="public" hint="Initializes the query objects with data." output="false">
        <cfargument name="dsn" type="string" required="true" hint="The datasource to use." />
        <cfquery name="variables.lookupTable1" datasource="#arguments.dsn#">
            SELECT * FROM [TblFoo]
        </cfquery>
        <cfquery name="variables.lookupTable2" datasource="#arguments.dsn#">
            SELECT * FROM [TblBar]
        </cfquery>
    </cffunction>

    <!--- Data Fetching Methods --->
    <cffunction name="getFoo" returntype="query" access="public" hint="Returns the contents of TblFoo." output="false">
        <cfreturn variables.lookupTable1 />
    </cffunction>

    <cffunction name="getBar" returntype="query" access="public" hint="Returns the contents of TblFoo." output="false">
        <cfreturn variables.lookupTable2 />
    </cffunction>
</cfcomponent>
Eric Kolb
:) Don't forget to add output="false" to all the functions to eliminate extra white space generated by CF.
Henry
I understand. What is the purpose of the two QueryNew definitions? Is it a way of declaring the variables so that the code is self-documenting, or is does it have a logical condition as to when it would be used?
cf_PhillipSenn
I guess they are there as safe guards, so that if you forgot to call init(), your getFoo() and getBar() won't throw exceptions. You can omit them though.
Henry
@cf_PhillipSenn - Henry is correct; I prefer to keep my returned items consistent. If I initialize something as an empty string and later change it as a Query, Array, or Struct, then there's always a chance I do a cfreturn on the variable and ColdFusion freaks out because it's not the type it's expecting to return. If it's destined to be a query, I make sure it's always a query. An empty result set is easier to manage than an exception.
Eric Kolb
@Henry - Yes, naturally. I left that off to keep my answer from stretching too wide. :)
Eric Kolb
@Eric - that's not an excuse, you put access="public" there, which is the default and not needed anyway... ;)
Henry
@Henry - Touché!
Eric Kolb
+1  A: 

If that's the only place you use the query object, you might want to cache the output of the cfselect drop-down box instead. :)

If you're not setting application scope variables in onApplicationStart() or onServerStart(), then don't forget to use <cflock>

Henry