【问题标题】:Every model, similar code - better way? (CakePHP)每个模型,类似的代码 - 更好的方法? (CakePHP)
【发布时间】:2012-03-01 18:01:48
【问题描述】:

在几乎每个模型中,我最终都会编写与以下示例代码相似的代码。它会检查是否发送了 limitorderconditions...等选项,并根据这些选项更改查询。

似乎必须有更好的方法,因为大多数这些东西在许多模型中一遍又一遍地重复。也许我可以使用一种行为?或者也许是我完全忽略的其他东西?

就模型代码而言,我觉得我试图重新发明轮子,但我真的很想知道轮子是什么 - 即大多数人如何管理他们的模型代码?我认为模型像这样是“正常的”?寻找这个整体“相似模型代码”概念的最佳实践。

//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 概念并将我所有的数据库内容保留在模型中。

【问题讨论】:

    标签: php cakephp cakephp-2.1 cakephp-model


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我理解/理解这一点,但不是我想要的。
      • 我认为您可以在控制器中实现类似 paginate 的方法(从参数中隐式读取信息,$paginate 并接受额外条件)。该方法将从您的参数、AppModel 或您的模型中的某些字段读取一些常规信息,并接受 $opts['conditions'] 中的额外条件。
      • 这听起来有点像我的想法——我不得不想象我不是唯一一个遇到这种情况的人——人们会这样做吗?如果是这样,有什么例子可以让我更好地理解吗?
      【解决方案3】:

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

      App::import('Model','TheBaseModel');
      class YourModel extends TheBaseModel {
      
      }
      
      class TheBaseModel extends AppModel {
      
          function OptionSetter() {
      
          }
      
      }
      

      【讨论】:

      • 你能解释一下“将类似模型扩展到基类”吗?
      • 给定上面的代码,函数OptionSetter将从YourModel获得,任何通用的选项构建代码都可以放在那里。
      • 听起来像是 Hope_is_grim 答案的更复杂版本,因为我可以在 AppModel 中放置一个函数,而不是创建一个新类来保存它,对吧?
      • 把它放在 app_model 中只是意味着该功能将适用于每个模型,而不是仅适用于适用的模型。 (好习惯!)
      • 明白了——谢谢。对我来说,它似乎值得在 AppModel 中使用,但是 - 如果我需要更具体的东西,很高兴知道这种方式。
      【解决方案4】:

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

      按照建议,扩展 AppModel 是推荐的方式。您可能应该查看 Inflector 方法以使其适用于每个子模型。

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

      lib/Cake/Console/Templates/default/classes
      

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

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

      【讨论】:

      • 我实际上并没有在烘焙,但是 - 听起来越来越像是我在 AppModel 中放入的东西。我以为有人会回答“哦,是的-这很常见,人们通常会这样做”。我很感激你的回答......会坚持一下,看看是否有人有任何其他想法,但是 - 你增加了以前关于 AppModel 的答案的权重 - 谢谢。
      • 不客气,很高兴它至少有点帮助。 :) 我经常对 model.ctp 文件进行更改以生成自定义 MVC,但是是的,我没有看到太多关于其他人这样做的文档,也不知道这有多普遍。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-29
      • 1970-01-01
      • 2020-01-29
      相关资源
      最近更新 更多