CakePHP Fat模型和瘦控制器 - appModel

Jam*_*s J 3 model-view-controller cakephp

为了追求最好的MVC实践,我试图确保我的所有代码都遵循胖模型,因此可能会有人将注意力集中在下面,并告诉我我是否在正确的轨道上?

目前在我的应用程序中我有

ExpenseClaims hasMany Expenses
Expenses belongsTo ExpenseClaims
Run Code Online (Sandbox Code Playgroud)

在我的pages/admin_index.ctp中,我需要获得属于每个列出的ExpenseClaim的所有费用的总和.

所以,我能看到的最好的FMSC方式是在AppModel中加载ExpenseClaim模型

App::uses('ExpenseClaim', 'Model');
Run Code Online (Sandbox Code Playgroud)

然后在AppModel中有一个我可以在app控制器中使用的功能(因为它在appModel中),我可以传递ExpenseClaim ID,它将返回所有相关费用的总和.

这是最正确的MVC方式,而不是在控制器中完成所有操作吗?

提前致谢

Nun*_*ser 8

正如您所说,最好的FMSC方法是在模型中编写函数.但是 !! 不要在AppModel中这样做,这是不好的做法.为什么要在AppModel中放置与两个(最多)模型相关的代码?每个模型都会继承该功能,这没有多大意义.假设你有一个"菜单模型"或"用户模型",它们继承一个totalExpenses函数是不合逻辑的,对吧?我知道你希望在每个控制器中都有这个功能,并且如果需要增加则查看,但这不是这样做的.

一步一步(实际上,只需两步):

1)在ExpenseClaim模型中,编写一个新函数来计算费用总额

class ExpenseClaim extends AppModel {
      /* definitions and validations here*/

      public function totalExpenses($id) {
          return $this->Expenses->find('count', array('conditions'=>
                                                   array('expense_claim_id' => $id)));
      }
}
Run Code Online (Sandbox Code Playgroud)

因此,在ExpenseClaimsController中,您可以调用此函数

$total = $this->ExpenseClaims->totalExpenses($the_id);
Run Code Online (Sandbox Code Playgroud)

2)现在,拥有在费用索赔模型中计算总数的功能是合乎逻辑的,因此可以在相应的控制器中使用,但是你说你想在pages/admin_index中使用它,让我们想象页面绝对没有连接索赔模型.那么,你可以做到

ClassRegistry::init("ExpenseClaims")->totalExpenses($the_id);
Run Code Online (Sandbox Code Playgroud)

要么

$this->loadModel("ExpenseClaims");
$this->ExpenseClaims->totalExpenses($the_id);
Run Code Online (Sandbox Code Playgroud)

(都在控制器中)你可以在不将该函数放入AppModel的情况下获得该值.

(顺便说一句,我写的代码应该可以工作,但你需要微调控制器和模型名称或者在这里和那里关闭括号,我还没有测试过它).

现在,这是一般的最佳实践.适用于大多数情况,功能更复杂.但是对于你的具体情况,你可能想看看蛋糕的counterCache,它可以计算一些东西,而不需要做太多.