# Enable/disable virtual fields ($\_virtual) at runtime

**URL:** <https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811>\
**Category:** Need Help\
**Created:** [August 27, 2018, 12:33am UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811 "2018-08-27T00:33:44Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![etipaced](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/etipaced/32/3338_2.png) [@etipaced](https://discourse.cakephp.org/u/etipaced)\
**Post date:** [August 27, 2018, 12:33am UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/1 "2018-08-27T00:33:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ADmad](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/admad/32/20_2.png) [@ADmad](https://discourse.cakephp.org/u/ADmad)\
**Post date:** [August 27, 2018, 12:59pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/2 "2018-08-27T12:59:42Z")

</div>

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()`.

---

<div class="post-metadata">

**Author:** ![etipaced](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/etipaced/32/3338_2.png) [@etipaced](https://discourse.cakephp.org/u/etipaced)\
**Post date:** [August 27, 2018, 4:15pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/3 "2018-08-27T16:15:47Z")

</div>

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

### Entity:

```auto
$_virtual = ['my_virtual_field'];

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

```

### Controller:

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

```

### Output:

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

```

I also tried creating a new entity like this:

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

```

…but I get the same result.

---

<div class="post-metadata">

**Author:** ![ADmad](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/admad/32/20_2.png) [@ADmad](https://discourse.cakephp.org/u/ADmad)\
**Post date:** [September 2, 2018, 6:50pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/5 "2018-09-02T18:50:39Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![etipaced](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/etipaced/32/3338_2.png) [@etipaced](https://discourse.cakephp.org/u/etipaced)\
**Post date:** [September 3, 2018, 2:39am UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/6 "2018-09-03T02:39:32Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![etipaced](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/etipaced/32/3338_2.png) [@etipaced](https://discourse.cakephp.org/u/etipaced)\
**Post date:** [September 3, 2018, 2:45am UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/7 "2018-09-03T02:45:09Z")

</div>

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

```auto
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.

---

<div class="post-metadata">

**Author:** ![cleftic](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/cleftic/32/1189_2.png) [@cleftic](https://discourse.cakephp.org/u/cleftic)\
**Post date:** [September 5, 2018, 7:53pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/8 "2018-09-05T19:53:29Z")

</div>

i need to get my hands dirty on OOP.[.](http://www.mp3cwitch.com.ng) still on Procedural PHP…

---

<div class="post-metadata">

**Author:** ![jmcd73](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/jmcd73/32/481_2.png) [@jmcd73](https://discourse.cakephp.org/u/jmcd73)\
**Post date:** [July 18, 2022, 12:52pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/9 "2022-07-18T12:52:02Z")

</div>

Just had to turn off virtual fields at runtime for a query. Hope this helps someone.

```auto
$destinations = $this->Shipments->find()
    ->select([
        'value' => 'destination',
    ])->distinct(['destination'])->where([
        'destination LIKE' => '%' . $term . '%',
    ]);

$destinations = $destinations->map(function ($destination) {
    return $destination->setVirtual([]);
});

$this->set(compact('destinations'));

```

---

<div class="post-metadata">

**Author:** ![dreamingmind](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/dreamingmind/32/1857_2.png) [@dreamingmind](https://discourse.cakephp.org/u/dreamingmind)\
**Post date:** [July 18, 2022, 4:49pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/10 "2022-07-18T16:49:29Z")

</div>

You could maintain two entity classes and use the `Table::setEntityClass` just before the query.

Personally I like this kind of OOPy solution. I think I’d actually inherit, like this:

```php
class Simple extends Entity {
   // all the basic stuff
}

class SvgVersion extends Simple {
  // all the heavy lifting and virtual fields
}

```

This means in you code you get three levels of type-hinting that can make your code easier to understand compared to a system where a single Entity class acts differently at different times

```php

//type hint examples

$this->svgProcess(SvgVersion $entity); //when only the best will do

$this->doSomething(Simple $entity); //when either entity type will work

$this->table->patchEntity(EntityInterface $entity, $data), when anything will work

```

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [July 18, 2022, 10:28pm UTC](https://discourse.cakephp.org/t/enable-disable-virtual-fields-virtual-at-runtime/4811/11 "2022-07-18T22:28:42Z")

</div>

Is there ever actually a need to have this virtual field included in any auto-generated output (JSON or array conversion)? If not, just don’t list it in the `$_virtual` array…
