Каждая модель, похожий код - лучший способ? (CakePHP) - PullRequest
3 голосов
/ 01 марта 2012

Практически в каждой модели я пишу код , аналогичный приведенному ниже примеру кода. Он проверяет, отправляются ли такие параметры, как 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 ]

5 голосов
/ 02 марта 2012

Если код одинаков для всех моделей, вы можете использовать поведение и просто присоединить его к моделям и изменить запрос с помощью обратного вызова beforeFind ().

Поместить код в AppModel также можно и вызывая его внутри beforeFilter () моделей, которым он нужен. Но я думаю, что поведение не так много, чтобы напечатать. ;) Так что я бы пошел за поведение. Если вам нужно больше фантазий, таких как конкретные параметры для модели при наличии набора значений по умолчанию, вы можете просто изменить поведение, чтобы поддержать это, объединяя параметры из свойства модели со значениями по умолчанию в поведении. Если бы вы были более конкретны, я мог бы предложить лучшее решение.

И, наконец: нет единого или 100% правильного способа сделать это. Я бы всегда выбирал решение, которое остается близко к MVC и следует за KIS.

1 голос
/ 01 марта 2012

IIRC, вы можете поместить обычные вещи в AppModel

0 голосов
/ 02 марта 2012

Исходя из предыдущего ответа, звучит так, как будто вы ищете способ повторить один и тот же код для нескольких моделей, но настроить его для каждой модели.

Как рекомендуется, расширение AppModel является рекомендуемым способом.Вероятно, вам следует изучить методы Inflector , чтобы он работал для каждой подмодели.

Я недавно начал делать редактирование файлов шаблонов, для модели это будетэто (в CakePHP 2.0.x):

lib/Cake/Console/Templates/default/classes

Откройте и отредактируйте файл model.ctp и добавьте туда свой код.

Когда вы печете свои модели (это то, чем я считаю вас)делать), это поможет воспроизвести ваш точный код в каждой из сгенерированных моделей.

0 голосов
/ 02 марта 2012

Вы могли бы попытаться расширить ваши аналогичные модели до базового класса и написать там общий набор параметров. Это может зависеть от того, сколько у вас особых случаев. Например, в базовом классе ваш установщик параметров может иметь дело с любыми аргументами, которые всегда присутствуют, и в особом случае вы можете переопределить функцию для любой модели, которая требуется.

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

}

class TheBaseModel extends AppModel {

    function OptionSetter() {

    }

}
...