3

在几乎每个模型中,我最终都会编写类似于以下示例代码的代码。它会检查是否发送了诸如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 概念并将我所有的数据库内容保留在模型中。

4

4 回答 4

5

如果所有模型的代码都相同,您可以使用行为并将其简单地附加到模型并使用 beforeFind() 回调更改查询。

将代码放入 AppModel 也可以,并在需要它的模型的 beforeFilter() 中调用它。但我认为这种行为是更少的打字工作。;) 所以我会选择这种行为。如果您在拥有一组默认值的同时需要更多的花哨功能,例如模型的特定选项,您可以通过将模型属性中的选项与行为中的默认值合并来简单地更改行为以支持该行为。如果您更具体,我可以提供更好的解决方案。

最后:没有通用或 100% 正确的方法来做到这一点。我总是会选择接近 MVC 并遵循 KIS 的解决方案。

于 2012-03-02T02:21:19.563 回答
1

IIRC,可以把常用的东西放到AppModel中

于 2012-03-01T18:07:31.400 回答
0

您可以尝试将类似模型扩展到基类,并在其中编写通用选项设置器。这可能取决于您有多少特殊情况。例如,在基类中,您的选项设置器可以处理始终存在的任何参数,并且在特殊情况下,您可以覆盖所需模型的函数。

App::import('Model','TheBaseModel');
class YourModel extends TheBaseModel {

}

class TheBaseModel extends AppModel {

    function OptionSetter() {

    }

}
于 2012-03-01T20:04:27.113 回答
0

根据前面的答案,听起来您正在寻找一种方法来跨多个模型复制相同的代码,但要为每个模型定制它。

正如推荐的那样,扩展 AppModel 是推荐的方法。您可能应该研究Inflector方法以使其适用于每个子模型。

我最近开始做的是编辑模板文件,模型是这样的(在 CakePHP 2.0.x 中):

lib/Cake/Console/Templates/default/classes

打开并编辑 model.ctp,然后在其中添加您的代码。

当您烘焙模型时(我相信您正在这样做),它将有助于在每个生成的模型中复制您的确切代码。

于 2012-03-01T22:26:15.627 回答