为了追求最好的MVC实践,我试图确保我的所有代码都遵循胖模型,因此可能会有人将注意力集中在下面,并告诉我我是否在正确的轨道上? / p>
目前在我的应用中我有
ExpenseClaims hasMany Expenses
Expenses belongsTo ExpenseClaims
在我的页面/ admin_index.ctp中,我需要获得属于每个列出的ExpenseClaim的所有费用的总和。
所以,我能看到的最好的FMSC方式是在AppModel中加载ExpenseClaim模型
App::uses('ExpenseClaim', 'Model');
然后在AppModel中有一个我可以在app控制器中使用的函数(因为它在appModel中),我可以传递ExpenseClaim ID,它将返回所有相关费用的总和。
这是最正确的MVC方式,而不是在控制器中完成所有操作吗?
提前致谢
答案 0 :(得分: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)));
}
}
因此,在ExpenseClaimsController中,您可以使用
调用此函数$total = $this->ExpenseClaims->totalExpenses($the_id);
2)现在,拥有在费用索赔模型中计算总数的函数是合乎逻辑的,因此可以在相应的控制器中使用,但是您说要在 pages / admin_index 中使用它,让我们想象页面与索赔模型完全没有关系。那么,你可以做到
ClassRegistry::init("ExpenseClaims")->totalExpenses($the_id);
或
$this->loadModel("ExpenseClaims");
$this->ExpenseClaims->totalExpenses($the_id);
(两者都在控制器中)你可以在不将该函数放入AppModel的情况下获得该值。
(顺便说一下,我编写的代码应该可以使用,但你需要微调控制器和模型名称或者在这里和那里关闭括号,我还没有测试过它。)
现在,这是一般的最佳做法。适用于大多数情况,功能更复杂。但是对于你的具体案例,你可能想看看蛋糕的counterCache,它可以保留数量,而不需要做太多。