Using Discriminated Entities When the Base Class Has No Knowledge of Child Classes

Discriminated entities are powerful in Quick, and allow you to create subclasses through simple changes to your entity definitions. However, one caveat is that the base class must know all of the possible discriminated entities:

// Array of all possible subclass entities
variables._discriminators = [

What if the base class has no knowledge of the possible child entities? For example, lets say you had a MaintenanceTask base entity, and the individual subclasses that extend the base class were established via the Coldbox configuration?

I thought of a possible solution, but it isn’t working out of the box. My idea was to use the diComplete() method of the base entity to grab the Coldbox settings and dynamically assemble the _discrimintators value. That way, all possible subclasses “register” themselves whenever the base class initializes.

Here’s what that approach might look like:

// MaintenanceTask.cfc (Base class for all maintenance tasks)

// list of discriminators comes from settings
property name="settings" inject="coldbox:setting:maintenance" persistent="false";

variables._discriminators = [];  // will be populated

function onDiComplete() {

    super.onDiComplete(); // make sure Quick can do it's thing.    

    // we need to populate the discriminators based on Coldbox settings
    // the settings key 'classList' contains an array of possible subclass entities.
    settings.classList.each( function( item ) {
        variables._discriminators.append( item ) );
    } );


The above solution seems to work when all the subclasses can be pulled from the Coldbox config. I wonder if there are any other ways this could be accomplished?

@DaveL I think that’s probably the best approach, though I would suggest appending the discriminators before you call super.onDIComplete(). That way, if anything changes in the implementation detection of parent discriminator entities, it will be able to detect them in the metadata inspection.

@elpete and I went back and forth on that variables._discriminators array when I was implementing it. It turned out to be the best solution to avoid recursion and re-looping Quick entities when they are scanned/registered. As such, dynamically appending is your best bet.

1 Like

One thing I’m not clear on, though. Why would you need to configure those in your Coldbox.cfc? If you declare a discriminated child, but never use that discriminator value, it would never look for it.

I wanted to come up with a way where a MaintenanceTask child entity could be developed separately from the core application (like a plug-in or module). I wanted to use all the benefits of subclassing, but didn’t want to couple the base class to all of its children.

Good tip about reversing the order of my code in diComplete(). I will try that.

@elpete, one issue I discovered when playing around with this is that property casts, don’t seem to work with discriminated entities, specifically the JsonCast@quick.

If I use the class like this, it works:


    property name="data" casts="JsonCast@quick"; 

Output: "data":{"rowsDeleted":0,"targetDate":"June, 25 2023 13:15:59"}

If I use the class like this, it doesn’t:


    property name="data" casts="JsonCast@quick"; 

Output: "data":"{\"rowsDeleted\":0,\"targetDate\":\"June, 25 2023 13:17:27\"}"

If this isn’t a simple fix, let me know and I will create an issue on Github.

Yeah, create a ticket please.

1 Like