在几乎所有模型中,我最终都将代码类似编写到下面的示例代码中。它会检查是否发送limit
,order
,conditions
...等选项,并根据该选项更改查询。
似乎必须有更好的方法,因为大多数这些东西在许多模型中反复重复。也许我可以使用一种行为?或者也许是我完全忽略的其他东西?
就模型代码而言,我觉得我已经尝试重新发明轮子,但我真的想知道轮子是什么 - 即大多数人如何管理他们的模型代码?我认为模特的“正常”是这样的?寻找这种整体“类似模型代码”概念的最佳实践。
//Restaurant model
function getRestaurants($opts = null) {
//initialize
$findType = 'all';
$params['conditions'] = array();
//order
$params['order'] = 'Restaurant.name ASC';
if(!empty($opts['order'])) $params['order'] = $opts['order'];
//limit
if(!empty($opts['limit'])) {
$params['limit'] = $opts['limit'];
if($params['limit'] == 1) $findType = 'first';
}
/*... ETC ETC
- can pass conditions, pricing, days open....etc
- obviously some things are only for this model, but things like
limit, order, conditions...etc are for all my models
*/
//pagination
$paginate = false;
if(isset($opts['paginate'])) {
if($opts['paginate']) {
$paginate = true;
}
}
//either return the paginate options just created
if($paginate) {
return $params;
//or return the restaurant data found
} else {
$data = $this->find($findType, $params);
return $data;
}
}
在某些情况下,还有更复杂的事情 - 无论是否根据发送的选项包含/加入某些模型等等。
我正在努力坚持使用MVC概念并将所有数据库内容保留在模型中。
答案 0 :(得分:5)
如果所有模型的代码相同,您可以使用行为并将其附加到模型并使用beforeFind()回调更改查询。
将代码放入AppModel也很好,并在需要它的模型的beforeFilter()中调用它。但我认为行为输入的工作量较少。 ;)所以我会去做这个行为。如果您需要更多类似于模型的特定选项而具有一组默认值,则可以通过将模型属性中的选项与行为中的默认值合并来简单地更改行为以支持该行为。如果您更具体,我可以提供更好的解决方案。
最后:没有共同或100%正确的方法来做到这一点。我总是会选择接近MVC并遵循KIS的解决方案。
答案 1 :(得分:1)
答案 2 :(得分:0)
您可以尝试将类似的模型扩展到基类,并在其中编写通用选项setter。这可能取决于您拥有多少特殊情况。例如,在基类中,您的选项setter可以处理始终存在的任何参数,在特殊情况下,您可以覆盖所需模型的函数。
App::import('Model','TheBaseModel');
class YourModel extends TheBaseModel {
}
class TheBaseModel extends AppModel {
function OptionSetter() {
}
}
答案 3 :(得分:0)
根据之前的回答,听起来您正在寻找一种在多个模型中复制相同代码的方法,但是为每个模型定制它。
根据建议,推荐使用扩展AppModel。您应该查看Inflector方法,以使其适用于每个子模型。
我最近开始做的是编辑模板文件,对于模型来说就是这样(在CakePHP 2.0.x中):
lib/Cake/Console/Templates/default/classes
打开并编辑model.ctp,然后在那里添加代码。
当您烘焙模型时(我相信您正在做的事情),它将有助于在每个生成的模型中复制您的确切代码。