Может ли виртуальное поле основываться на связанных данных в cakephp? - PullRequest
0 голосов
/ 28 марта 2012

Возможно ли для виртуального поля var быть суммой поля из связанной таблицы?

Например, например, в модели Счета-фактуры, вы могли бы иметь

public $virtualFields = array(
    'invoiceNett' => 'SUM(InvoiceLine.nett)'
);

но, очевидно, только СУММИРОВКА строк, принадлежащих этому счету?

Спасибо.

== Использование CakePHP 2.0

Ответы [ 4 ]

0 голосов
/ 28 марта 2012

Определение вашего виртуального поля в соответствующей модели будет иметь больше смысла.

Если этого не сделать, вы нарушите схему MVC.

Вы можете использовать это виртуальное поле из других связанных моделей.

Если вы не хотите использовать их во всех связанных моделях, вы всегда можете использовать поле атрибут при определении отношений.

public $hasMany = array(
    'IwantVirtualField' => array(
        'className' => 'MyModel',
        ...
    )
);

В модели, где вам не нужно виртуальное поле public $ ownTo = array ( 'IwantVirtualField' => array ( 'className' => 'MyModel1', 'fields' => array ('MyModel1.id', 'MyModel1.name') ... ) );

0 голосов
/ 28 марта 2012

Теоретически, да, если эта связанная таблица является ассоциированной, которая объединена (ownTo и hasOne).

Однако это было бы плохой идеей, потому что, если вы решите не включать эту таблицу, вы получите ошибку SQL.

Было бы лучше иметь отдельную функцию для сбора данных или создания виртуального поля, которое было бы вложенным запросом SQL.

0 голосов
/ 28 марта 2012

Вы можете использовать обратный вызов afterFind, чтобы получить сумму. Это позволяет избежать сохранения рассчитанных значений, чего следует избегать, когда это возможно.

function afterFind($results)
{
    foreach($results as &$result)
    {

        /*
        Use something like:

        $this->InvoiceLine->find('all', array('fields'     => array('SUM(InvoiceLine.nett) as total'), 
                                              'conditions' => array('invoice_id' => $result['Invoice']['id'])));
        */
    }
    unset($result);
}
0 голосов
/ 28 марта 2012

Насколько я знаю, лучший способ сделать это - иметь действительное поле total и обновлять его при каждом сохранении данных (вероятно, с помощью метода обратного вызова afterSave ).

Итак, каждый раз, когда InvoiceLine сохраняется, вы запускаете некоторый код, чтобы обновить связанный Invoice с новым итогом.

//InvoiceLine model
public function beforeSave() {
    //code to update Invoice's "total" field
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...