1

嗨,我已经完成了 find() 并在一些结果中添加了一个新字段:

$approved = $this->ExpenseClaim->find('all', array('conditions'=> array('ExpenseClaim.claim_status_id' => '3')));
$i = 0;
foreach ($approved as $ap) {
    $approved[$i]['ExpenseClaim']['claimTotal'] = $this->ExpenseClaim->expenseClaimTotal($approved[$i]['ExpenseClaim']['id']);
    $i++;
}

我现在需要将它传递给分页,但是我在这里读到你不能这样做,我必须创建另一个模型才能仅在这个特定的查找上使用 afterFind() 方法。

所以我创建了名为的新模型ExpenseClaimTotal并将 UseTable 设置为

public $useTable = 'expense_claims';

然后在新模型 afterFind() 方法中我做了一个简单的调试:

public function afterFind($results, $primary = false) {
    debug($results);
    //return $results;
}

但是,当我现在尝试在 pagesController 中针对这个新模型进行查找时,它失败了:

$this->loadModel('ExpenseClaimTotal');

$approved = $this->ExpenseClaimTotal->find('all', array('conditions'=> array('ExpenseClaim.claim_status_id' => '3')));

这是我得到的错误:

Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ExpenseClaim.claim_status_id' in 'where clause'

SQL Query: SELECT `ExpenseClaimTotal`.`id`, `ExpenseClaimTotal`.`user_id`, `ExpenseClaimTotal`.`claim_status_id`, `ExpenseClaimTotal`.`created`, `ExpenseClaimTotal`.`modified`, `ExpenseClaimTotal`.`approved`, `ExpenseClaimTotal`.`approved_by`, `ExpenseClaimTotal`.`declined_by`, `ExpenseClaimTotal`.`date_submitted` FROM `expenses`.`expense_claims` AS `ExpenseClaimTotal` WHERE `ExpenseClaim`.`claim_status_id` = 3

文档中似乎没有太多关于在一张桌子上使用 2 个模型

4

1 回答 1

2

您不想对数组进行分页

您已经在执行查找,执行查找然后对结果数组进行分页是不明智的。

只需直接对模型数据进行分页并在此过程中注入您的总值。因此-如果您将原始的“在某些结果中添加了新字段”逻辑放入模型中:

class ExpenseClaim extends AppModel {

    public function afterFind($results, $primary = false) {

        foreach ($results as &$ap) {
            if (isset($ap['ExpenseClaim']['id'])) {
                $ap['ExpenseClaim']['claimTotal'] = $this->expenseClaimTotal($ap['ExpenseClaim']['id']);
            }
        }

        return $results;
    }
}

您的控制器代码变得简单:

public function index() {

    $conditions = array('ExpenseClaim.claim_status_id' => '3');
    $data = $this->paginate($conditions);

    $this->set('data', $data);
}

并且代码很简单并且“可以正常工作”。

增强功能

以上是实现预期结果的最简单方法,但有一些缺点 - 即它会在几乎所有发现上调用总方法。

根据您正在做什么,您可能希望例如:

缓存您的总数

如果合适,您可以通过简单地将字段“claim_total”添加到数据库中来消除问题,并在它发生变化时重新计算。这意味着从费用报销模型中读取时绝对没有额外的逻辑。

使用自定义查找类型

如果您不想重新计算所有查找的总数 - 您可以创建自定义查找类型

class ExpenseClaim extends AppModel {

    public $findMethods = array('allWithTotals' =>  true);

    protected function _findAllWithTotals($state, $query, $results = array()) {
        if ($state === 'before') {
            return $query;
        }

        foreach ($results as &$ap) {
            $ap['ExpenseClaim']['claimTotal'] = $this->expenseClaimTotal($ap['ExpenseClaim']['id']);
        }

        return $results;
    }

然后在您的分页调用中使用它

public function index() {
    $this->paginate['findType'] = 'allWithTotals'; # <-

    $conditions = array('ExpenseClaim.claim_status_id' => '3');
    $data = $this->paginate($conditions);

    $this->set('data', $data);
}

这样,只有 index 方法会触发添加总计的调用。

于 2013-06-20T10:21:20.783 回答