Get Related Active Record?

5 views
Skip to first unread message

Daniel Lancelot

unread,
Dec 11, 2008, 11:30:25 AM12/11/08
to dataf...@googlegroups.com
Hi,

I was wondering if there was already any built in functionality within DataFaucet to get a single related active record object:

For instance, I have a site table which has 1 related template for each site (site is the m in a m:1 relationship)

so if siterecord is an instantiated active record for the site table, I want to be able to call something like siterecord.getTemplate() to get the related template active record.

I would expect this to be lazy loaded - so it would only get the template data from the db the first time siterecord.getTemplate() is called.

Is there any built in functionality that helps me do this?


Best regards,

Dan

Isaac Dealey

unread,
Dec 11, 2008, 12:57:35 PM12/11/08
to dataf...@googlegroups.com
> I was wondering if there was already any built in functionality
> within DataFaucet to get a single related active record object:
>
> For instance, I have a site table which has 1 related template for each site
> (site is the m in a m:1 relationship)
>
> so if siterecord is an instantiated active record for the site table, I want
> to be able to call something like siterecord.getTemplate() to get the
> related template active record.

Not built in currently. For a many to one relationshiop like that I
typically add a custom method like

<cffunction name="getTemplate" access="public">
<cfreturn getDatsource().getActiveRecord(
className="my.template.class",
objectid=getValue("templateid")) />
</cffunction>

> I would expect this to be lazy loaded - so it would only get the
> template data from the db the first time siterecord.getTemplate() is
> called.
>
> Is there any built in functionality that helps me do this?

I load active record objects primarily as transients rather than caching
them. There's an exception in the Member/Security plugin for the onTap
framework that the members for example are cached in memory and lazy
loaded like this. What I have there is a "MemberFactory" which I get
from my IoC factory and then call getMember(memberid) and it does the
work of lazy-loading the individual member objects.

So what you might be looking for here is to override the init() method
of the active record for the site so that you can pass in a
"TemplateFactory" and then you can use that to lazy-load your template
records via a custom function that looks like this:

<cffunction name="getTemplate" access="public">
<cfset var tf = getTemplateFactory() />
<cfreturn tf.getTemplate(getValue("templateid")) />
</cffunction>

Or alternatively, dependent upon how much data and behavior is in the
template table, you might prefer to simply add the template data
directly into the site record object, so that the site gets its data
from multiple tables. This is something that we see often in content
management systems where all content has a record in a "content" table,
but then there's an extra table to hold data specific to its type (i.e.
page, news, etc.). As long as you've got a foreign key constraint
between the site table and the template table, this should be pretty
easy, you can just use this:

<cfcomponent extends="datafaucet.system.activerecord">
... properties here ...
<cfset setTable("site") />
<cfset addTable("template") />

</cfcomponent>

And then your site will have all the columns in the template table as
additional properties.

If you prefer not to have a foreign key constraint (or you have a
specific reason not to), then there are some extra arguments ot the
addTable method. They are probably "column" and "references" although
I"m not certain of that. ;)

Let me know how these hints work for you. :)

hth,
ike


--
[ ike ] founder - DataFaucet ORM

phone: 781.769.0723

http://www.datafaucet.com


Daniel Lancelot

unread,
Dec 11, 2008, 1:23:54 PM12/11/08
to dataf...@googlegroups.com
Hi Ike,

Ok, looks simple enough.

With regards to cacheing - its not so much having the records cached across the application - but avoiding the need to hit the db multiple times when repeatedly referencing getTemplate()

For instance I am overriding a number of my setters to compare the site record value to the template record value - and if they match, set the site value to empty string (and conversely on the getters, return the template value if the site value is an empty string...)

For this I think I will just set variables. template record the first time getTemplate is called...


Adding the template data to the site record is not reallly an option, as the site record contains the same fields as the template - I know I could get round that with prefixes etc. - but I don't think this is appropriate in this case.


Thanks again,

Cheers,

Dan

Isaac Dealey

unread,
Dec 11, 2008, 1:31:04 PM12/11/08
to dataf...@googlegroups.com
> For instance I am overriding a number of my setters to compare the
> site record value to the template record value - and if they match,
> set the site value to empty string (and conversely on the getters,
> return the template value if the site value is an empty string...)
>
> For this I think I will just set variables. template record the first
> time getTemplate is called...

Oh okay, just lazy-loading it within the individual request, not for the
lifespan of the application... yeah, that's actually a use case I've had
before, so I'm not sure why it didn't occur to me. ;)

> Adding the template data to the site record is not reallly an option,
> as the site record contains the same fields as the template - I know I
> could get round that with prefixes etc. - but I don't think this is
> appropriate in this case.

Gotcha. Yeah, and if this is a pre-existing schema (which it sounds like)
possibly with existing CF code already devoted to that structure it
probably makes more sense to keep what you have unless you suddenly
discover some really compelling reason to change. And I don't think I
would consider the addTable() technique compelling in that sense because
it doesn't add value for your end-user. ;)

Reply all
Reply to author
Forward
0 new messages