CakePHP 3:添加额外字段以从模板访问

CakePHP 3: add extra field to access from template

我正在使用 CakePHP 3.6

我有两个模型 UsersWalletTransactions

WalletTransactionsUsersuser_id 相关联,并且有一个列 price.

我正在使用以下代码来显示用户列表

UsersController.php

public function index()
{
    $users = $this->Users->find();

    $this->set(compact('users'));
}

users/index.ctp

<?php foreach($users as $user): ?>

    <?= $user->name ?>

<?php endforeach; ?>

现在,我想在模板的用户列表中显示来自 WalletTransactionsprice 的总和。

为此,我编写了一个函数来获取 WalletTransactionsTable.php

price 的总和
public function walletBalance($user_id)
{
    $total_balance = 0;

    $walletTransactions = $this->find()
        ->where([
            'user_id' => $user_id
        ]);

    foreach ($walletTransactions as $transaction) {
        $total_balance += $transaction->price;
    }

    return $total_balance;
}

并在 User.php 实体中设置一个 属性 函数 class

protected function _balance()
{
    $user_id = $this->_properties['id'];

    $WalletTransactions = TableRegistry::get('WalletTransactions');

    $transaction = $WalletTransactions->walletBalance($user_id);

    return $transaction;
}

在模板中users循环时使用

<?= $user->balance ?>

它什么都不打印。

如何在模板中显示其他模型的值?

访问器必须以_get开头,即_getBalance。然而,理想情况下,实体应该是愚蠢的数据容器,让它们发出查询并不是最好的主意,更不用说每次访问 属性 时发出查询是相当低效的。

我建议使用例如自定义查找器。此外,无需检索所有交易并在 PHP 级别进行计算,这可以在 SQL 级别轻松完成:

// UsersTable

public function findWithWalletBalance(\Cake\ORM\Query $query, array $options)
{
    return $query
        ->leftJoinWith($this->WalletTransactions->getName())
        ->select([
            'balance' => $query->func()->sum($this->WalletTransactions->aliasField('price'))
        ])
        ->group(array_map([$this, 'aliasField'], (array)$this->getPrimaryKey()))
        ->enableAutoFields(true);
}
// UsersController

public function index()
{
    $users = $this->Users->find('withWalletBalance');

    $this->set(compact('users'));
}

另见