Календарь на сайте CakePHP, но CakeBook говорит, что не следует использовать модель в компоненте - PullRequest
1 голос
/ 20 июня 2011

У меня есть небольшая вещь типа виджета календаря на многих страницах моего сайта. Цель состоит в том, чтобы получить события из категории X, которые попадают между датами Y и Z.

Мое предположение (я новичок в CakePHP) состояло в том, что я должен создать компонент и заставить его выполнять запрос. Примерно так:

class CalendarComponent extends Object {

    var $uses = array('Event');

    function getEvents($category = null, $date = null, $limit = null) {
        $events = $this->Event->find('list', //conditions to get correct events
        return $events;
    }

}

НО, согласно этой странице CakeBook :

Для доступа / использования модели в компоненте как правило, не рекомендуется

Итак - где бы я мог хранить этот вызов логики / модели, если бы не компонент? По общему признанию, я еще не использовал компонент (или не создал его в любом случае) из-за недостатка понимания того, как я должен его использовать - любой фрагмент совета по этому вопросу также ОЧЕНЬ приветствуется.

Ответы [ 2 ]

3 голосов
/ 20 июня 2011

Большой вопрос, на мой взгляд, и я думаю, что он возникает довольно часто.Я на самом деле имел дело с подобной проблемой, когда я хотел, чтобы какой-то сбор данных или функциональность в масштабе всего сайта были добавлены в компонент.

Первое, что нужно иметь в виду:

Книга является руководством.

Эти «правила» не являются правилами.Если есть хорошая причина для нарушения правила, и вы понимаете , почему нарушается правило, тогда сломайте эту чертову вещь!Сам пирог нарушает это правило довольно часто.

Основные компоненты, которые требуют / используют модели:

  • Acl
  • Auth
  • Сеансы (довольно положительно, вы можете сохранить данные сеанса в модели)

Итак, очевидно, есть случаи, когда вам нужно использовать модель внутри компонента.Как ты это делаешь?

Ну, есть пара разных способов.Чем я закончил?Примерно так:

<?php

    ModelLoadingComponent extends Object {

        public function startup($controller) {
            $controller->loadModel('Model');

            $this->Model = $controller->Model;
        }

    }

?>

Вот и все!Теперь ваш компонент настроен на использование $this->Model ... так же, как в контроллере.

Редактировать:

Извините, чтобы уточнить: нет, вы нене нужно настраивать новый компонент для загрузки моделей.Я показываю пример того, как вы можете загрузить компонент в любой модели.Функция startup, которую я использовал, является специфичным для компонента обратным вызовом, их множество http://book.cakephp.org/view/998/MVC-Class-Access-Within-Components. Эти методы обратного вызова делают компоненты намного более удобными для работы.Я настоятельно рекомендую просмотреть эту часть руководства по компонентам, если ничего другого.

Если вы работали внутри объекта AppController, вы могли бы вызвать $this->loadModel(), но мы не работаем с AppController!Мы работаем с компонентом, действительно Object.Там нет Object::loadModel(), поэтому мы должны придумать другой способ получить эту модель.Именно здесь $controller вступает в игру в нашем startup обратном вызове.

Когда Cake вызывает метод startup, он передает объект $controller, с которым он работает, в этой диспетчеризации в качестве первого параметра.Благодаря этому мы можем получить доступ к методам контроллера ... как loadModel().

Почему мы делаем это таким образом?

Ну, мы могли бы использовать ClassRegistry::init('Model') в каждом из нашихКомпонентные методы, которые должны использовать модель.Если у вас есть 10 методов в вашем компоненте, и только один из них использует модель, это может сработать.Однако что, если у вас есть 10 методов в вашем компоненте, и все 10 из них используют модель?Ну, вы бы звонили ClassRegistry :: init ('Model') 10 раз!Это большая нагрузка, когда вам действительно нужен только один модельный объект.С помощью этого метода компонент создает один объект модели.Тот, который мы создаем в startup.

Надеюсь, это прояснит ваши вопросы и даст некоторое представление о том, почему я использую этот метод для моделей в компонентах.

Редактировать: Добавлено уточнение кода после того, как япровел некоторые эксперименты.

1 голос
/ 20 июня 2011

Я думаю, что в этом случае написание компонента является излишним, и было бы более разумно использовать метод getEvents в модели Event.

...