Можно ли определить виртуальные поля (вызовы функций SQL) в сущностях? - PullRequest
0 голосов
/ 17 сентября 2018

Это их путь, мы можем добавить пользовательскую функцию MySQL в Entity

protected $_virtual = ['check_tenant' => '(check_tenant(Tenants.id))']; 

Я бы хотел вызвать следующий запрос с помощью find() метода

//SELECT id, first_name, check_tenant(Tenants.id) FROM tenants AS Tenants

$this->Tenants->find()->all();

Если я могу определить пользовательскую функцию MySQL в виртуальном поле, она автоматически вернется в наборе результатов

Я могу передать новое поле в select() метод

$this->Tenants->find()
->select(['id', 'check_tenant' => '(check_tenant(Tenants.id))'])->all();

Но я бы хотел определить глобально, чтобы новому полю не нужно было проходить каждый find вызов

1 Ответ

0 голосов
/ 17 сентября 2018

Виртуальные свойства в CakePHP 3.x не совпадают с виртуальными полями в CakePHP 2.x, последние использовались в запросах SQL, а первые используются вУровень PHP, обычно с данными, уже присутствующими в объекте.

Если вы хотите, чтобы ваше пользовательское поле присутствовало в всех запросах, то вы можете, например, использовать событие Model.beforeFind() для изменениязапросы соответственно:

// in TenantsTable class

public function beforeFind(\Cake\Event\Event $event, \Cake\ORM\Query $query, array $options)
{
    return $query
        // select custom fields (functions builder usage not required, but advised)
        ->select(function (\Cake\ORM\Query $query) {
            return ['check_tenant' => $query->func()->check_tenant([
                'Tenants.id' => 'identifier'
            ])];
        })
        // ensure that the tables default fields are being selected too
        ->enableAutoFields(true); // autoFields() before CakePHP 3.4
}

Еще один менее инвазивный вариант - это пользовательские средства поиска, которые вы явно используете там, где они вам нужны:

// in TenantsTable class

public function findWithTenantCheck(\Cake\ORM\Query $query, array $options)
{
    return $query
        ->select(/* ... */)
        ->enableAutoFields(true);
}
// query data

$query = $this->Tenants->find('withTenantCheck');

См. также

...