Enable/disable virtual fields ($_virtual) at runtime


#1

I have some heavy-lifting occurring in my entity’s accessors but only need these for drawing a complex SVG chart that I’m building. I’m loading the data into the DOM via AJAX so these virtual fields are in my $_virtual class member. However, sometimes I just need the basic db fields and not any of the calculated values from my accessors.

How can I “turn off” these values on a per-query basis?

I’ve tried just selecting the ones I need (via fields key in a contain), but the virtual ones still come back to me.


#2

I assume you are sending serialized (JSON) response. To prevent the virtual fields from being included in serialized data set them as hidden using Entity::setHidden().


#3

Perhaps I’m not using it correctly, but it doesn’t work as I expect. My test case:

Entity:

$_virtual = ['my_virtual_field'];

protected function _myVirtualField()
{
    # Running some complex operations.
    return 'value';
}

Controller:

$entity = $this->Entities->newEntity();
$entity->setHidden(['my_virtual_field']);
dd($entity);

Output:

{
    'my_virtual_field' => 'value',
    ...
}

I also tried creating a new entity like this:

$entity = $this->Entities->newEntity([]);

…but I get the same result.


#5

Check dd($entity->toArray()) or dd(json_encode($entity)) instead of dd($entity).


#6

Ok debugging with toArray() shows that the property isn’t there, but my db queries in that accessor are still executing. So I’m wondering if there’s a way to simply turn this off on a case by case basis? It’s looking like there isn’t, however.

Thanks for your help.


#7

Looks like adding the following to the top of my accessor logic does the trick:

if (in_array('my_virtual_field', $this->getHidden())) {
    return null
}

It’s a bit of configuration but since it’s only for one special-case property, it’s not a big deal.


#8

i need to get my hands dirty on OOP.. still on Procedural PHP…