использование пользовательских моделей, наследование от запеченных моделей в CakePHP

Сообщество,

Из других API-интерфейсов MVC-Frameworks/persistence-API, таких как спящий режим в мире java, я знаю передовой механизм наследования от сгенерированной структуры модели и использования этих унаследованных моделей в качестве DAO в вашем приложении. Мне особенно нравится этот подход, потому что вы можете легко перепечь свои модели после изменений в базе данных, чтобы настроить ассоциации моделей, не перезаписывая свой код доступа (пользовательские методы, обратные вызовы событий и т. д.).

Однако я не смог найти ничего подобного для CakePHP.

Что я уже пробовал

Мой первый подход к достижению этой цели заключался в использовании функции CakePHP App::build(). Я зарегистрировал новые плагины-директивы для запеченных моделей и контроллеров и заменил пакеты моделей и контроллеров по умолчанию моими собственными папками реализации:

в bootstrap.php:

App::build(array(
        'BakedModel' => array(ROOT. DS . APP_DIR . '/Model/'),
        'BakedController' => array(ROOT. DS . APP_DIR . '/Controller/')
    ),
    App::REGISTER
);

App::build(array(
        'Model' => array(ROOT. DS . APP_DIR . '/Model/impl/'),
        'Controller' => array(ROOT. DS . APP_DIR . '/Controller/impl/')
    ),
    App::RESET
);

После того, как я создал свои собственные контроллеры и модели в папках impl, импортируя и наследуя от ссылающейся запеченной модели:

моя пользовательская модель:

App::uses('Inmessage', 'BakedModel');

class InmessageDao extends Inmessage {
    var $useTable = 'inmessages';
    ...
}

Однако это работает, пока я назначаю новое уникальное имя для пользовательских классов моделей (т.е. InmessageDao расширяет Inmessage). Проблема с использованием другого имени модели заключается в том, что все унаследованные отношения моделей относятся не к другим моим пользовательским реализациям, а, конечно, к запеченным моделям. Поэтому мне нужно было бы скопировать и изменить все отношения в моих пользовательских моделях, чтобы заставить их работать, в которых тогда отсутствует преимущество наследования. Так что я ничего не получаю здесь.

Если я попытаюсь использовать идентичное имя для своих пользовательских моделей, Cake больше не сможет адресовать разные объекты. Такой подход приводит к исключению ClassNotFoundException.

class Inmessage extends Inmessage {
    ...
}

Итак, мой вопрос:

Кто-нибудь знает, есть ли способ правильно наследовать модели и использовать их вместо запеченных моделей?

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

Заранее спасибо!

пс. В настоящее время я использую версию 2.5.8.


person TurbuLenz    schedule 13.02.2015    source источник


Ответы (2)


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

Это не так, как это работает в CakePHP. Если вы измените схему, модель обнаружит изменение, за исключением того, что вы описали схему вручную, используя Model::$_schema.

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

Однако ассоциации будут обнаружены Cake, если схема БД соответствует соглашениям CakePHP. Таким образом, вы можете сделать $User->Profile, если есть таблица профилей с полем user_id - даже без создания ассоциации вручную. Но это не рекомендуется.

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

Также не вижу проблемы добавить новых ассоков вручную, это дело нескольких секунд. Нет необходимости повторно запекать модели снова и снова после того, как вы их запечете.

Если вы ищете место для реализации повторно используемого кода, взгляните на Behaviors или поместите его в AppModel, если эта функциональность необходима в каждой модели вашего приложения.

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

person floriank    schedule 13.02.2015
comment
Я знаю о встроенных механизмах ассоциаций моделей тортов из соглашений об именах. Я просто ищу способ облегчить работу с частыми изменениями базы данных на этапе разработки. И поскольку другие фреймворки предлагают решения здесь, я подумал, что торт тоже может. Может быть, это просто не так. В любом случае спасибо за ответ @burzum! - person TurbuLenz; 13.02.2015
comment
Что точно вам не хватает? Можете ли вы показать мне пример в одной из этих других фреймворков без php? Существует плагин миграции для Cake 2 и 3, чтобы правильно изменить саму базу данных. - person floriank; 13.02.2015
comment
т.е. с помощью Hibernate вы создаете файлы моделей (называемые pojo или dao) из базы данных, аналогичные скрипту выпечки тортов. Но вы не должны редактировать эти файлы, вместо этого вы наследуете их и вносите изменения только в свои унаследованные модели-классы. Эти унаследованные модели используются в приложении, а не сгенерированные. Если у вас есть какие-либо изменения в базе данных, вы просто регенерируете и перезаписываете свои pojos/daos, и все ваши пользовательские модели наследуют новые изменения (атрибуты, ассоциации, ...), но ваши пользовательские функции остаются нетронутыми. - person TurbuLenz; 13.02.2015
comment
Итак, если вы перенесете эту идею на торт, pojos/daos — это запеченные модели. Я ищу способ расширить их в другом классе и позволить фреймворку использовать их вместо сгенерированных. Я думаю, что этого можно добиться с помощью пространств имен PHP, которые не поддерживаются тортом в версии 2. Я надеялся, что кто-нибудь сможет доказать, что я ошибаюсь ;-) - person TurbuLenz; 13.02.2015
comment
Вы можете создать свои собственные шаблоны для выпечки и позволить ему сгенерировать другой класс по соглашению ‹tablename›BaseModel.php поместить туда assocs и изменить шаблон модели, чтобы он наследовал его вместо AppModel. Однако я не думаю, что это нужно для CakePHP, я думаю, вы пытаетесь навязать что-то, что здесь не нужно, потому что вы к этому привыкли. Как я уже сказал, добавить новых помощников очень просто. У нас не было необходимости в чем-то подобном, даже в постоянно растущем приложении с ~ 560 таблицами. - person floriank; 13.02.2015
comment
Возможно, вы правы, возможно, я немного застрял в корпоративных структурах Java ;-) Использование собственного сценария выпечки, генерирующего мою желаемую структуру модели, звучит многообещающе, я попробую. Спасибо за вашу поддержку @burzum! - person TurbuLenz; 13.02.2015
comment
Добро пожаловать, но имейте в виду, что вам придется проделать большой объем работы, чтобы все заработало правильно! - person floriank; 13.02.2015

Я думаю, что простой способ сделать это в Cake — просто создать «плагин», хранить модели внутри этого плагина и при необходимости включить в контроллеры «plugin.model».

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

Я надеюсь, что это может помочь!

person Newton Pasqualini Filho    schedule 13.02.2015
comment
Спасибо за ваш вклад в этом вопросе. Это интересный подход. Я попробую в следующий раз. Это я решил, используя пользовательский шаблон выпечки для своих моделей, который создает две модели: базовую модель с префиксом, содержащую отношения, и обычную модель, наследующую базовую модель. Шаблон также гарантирует, что реализованные модели никогда не будут перезаписаны. Он стабильно работает уже два года и избавил меня от многих головных болей. - person TurbuLenz; 10.03.2017