A Recursive Function to Gather CFC Metadata for Inherited Properties
Posted At : December 21, 2009 1:40 PM | Posted By : Bob Silverberg
Related Categories: ColdFusion, CF ORM Integration, BPO
Charlie Stell made a comment on my last post about my Base Persistent Object project, pointing out that my populate method did not take inherited properties into account. When I first developed it I wasn't using inheritance with ColdFusion ORM, as I'm coming from a Transfer background and Transfer doesn't really support inheritance. On a recent project using CF ORM I did implement an inheritance scheme and decided to update my populate method to support that.
The reason that the current populate method does not support inheritance is that is simply looks at the properties array that is included in the cfc metadata of the current object. That array of properties does not include any inherited properties. To find those you need to look at the extends key in the metadata structure and check for any properties of the object that the current object extends, and, of course any objects that that extends, etc. You could potentially have several levels of parents as you move up the inheritance hierarchy.
I decided that the best approach would be to write a recursive function that would return all of the properties of an object as an array, including all properties of any of the object's parents. In his comment Charlie provided some sample code that he is using, and I took his suggestion and made a couple of changes to it. Here's the code:
2 local.prop = 1;
3 if (structKeyExists(arguments.md,"properties")) {
4 for (local.prop=1; local.prop <= ArrayLen(arguments.md.properties); local.prop++) {
5 if (not ArrayContains(arguments.props,arguments.md.properties[local.prop].name)) {
6 arrayAppend(arguments.props,arguments.md.properties[local.prop]);
7 }
8 }
9 }
10 if (arguments.md.extends.fullname neq "WEB-INF.cftags.component") {
11 arguments.props = collectAllProperties(arguments.md.extends,arguments.props);
12 }
13 return arguments.props;
14}
To use this function, you simply pass in the metadata of an object into the md argument, so if I wanted to get the metadata for all properties for a User object I would do something like:
2userProperties = collectAllProperties(getMetadata(User));