#php #cakephp #inheritance #model
#php #cakephp #наследование #Модель
Вопрос:
Я планирую создать веб-сайт с использованием Cakephp, и одним из «требований» является использование наследования в базе данных.
Родительский объект притворяется, что обладает общими свойствами, но, что наиболее важно, идентификатором (ключевым атрибутом), который передается его подразделам, которые, конечно же, имеют свой собственный набор атрибутов.
Поддерживает ли Cakephp эту функцию? Если это так, кто-нибудь может предоставить простой пример использования наследования? (кстати, не множественное наследование)
Я буду признателен за ваши ответы.
Комментарии:
1. Вау! Спасибо, ребята. Я вижу, что существует слишком много способов решить эту проблему. Но все они кажутся непреодолимыми, по крайней мере, для новичка в cakephp вроде меня. Не могли бы вы опубликовать пример кода или ссылку на учебное пособие, пожалуйста?
2. Интересно, если вы глубоко покопаетесь в Cakephp, вам все еще нужно это наследование в стиле ООП или ORM hasOne, многие функции HASMAN эффективны, что вы описали в своей теме.
Ответ №1:
хотя я не думаю, что он поддерживает это напрямую, вы можете сделать это с помощью некоторого набора класса magic. один из самых потрясающих классов в мире.
http://book.cakephp.org/view/1487/Set
и
http://book.cakephp.org/view/1508/merge
если вы делаете довольно простые вещи, array_merge () сделает это и за вас
Вы могли бы легко создать поведение, которое выполняет это в обратном вызове afterFind(), чтобы оно прозрачно выполнялось в одном месте и все было готово для вашего просмотра, просто выполнив обычный $this-> Model-> find(‘all’) и т. Д
Комментарии:
1. Я не совсем понимаю это, особенно если вы сталкиваетесь с CRUDs. Можете ли вы проиллюстрировать это простым примером кода?
Ответ №2:
Вам нужно будет реализовать это поведение с помощью встроенного в CakePHP реляционного отображения (hasOne):
http://book.cakephp.org /#!/view/1039/Ассоциации-Связывание-моделей-вместе
Затем вы можете изменить класс AppModel и реализовать метод afterFind (для работы со всеми моделями) и обработать / объединить данные.
Комментарии:
1. Итак, вы пытаетесь решить это с помощью композиции, правильно ли это? С отношением HAS-A вместо IS-A?
Ответ №3:
Вы могли бы рассмотреть возможность использования Doctrine в качестве ORM, который поддерживает наследование через агрегацию столбцов: http://dqminh.com/integrate-doctrine-orm-with-cakephp-part-1
Комментарии:
1. он указал cakephp: если вы сможете заставить Doctrine работать с системой отношений Cake, я верну ваш голос обратно.
2. Предоставленная ссылка просто загружает doctrine через composition в AppModel — у нее нет поддержки отношений, нет поддержки проверки и нет синтаксического сахара find, подобного обычному cake orm. Если ему удастся поддержать нечто большее, чем просто включить doctrine в качестве поставщика и сообщить модели, чтобы она не использовала источники данных cake, то, возможно, это было бы жизнеспособным решением. Похоже, он либо не планирует внедрять это дальше, либо до этого еще далеко.
Ответ №4:
Это поведение, написанное некоторое время назад — оно может быть старым, но оно должно дать вам очень хорошую основу для понимания того, как управлять STI (наследованием одной таблицы) с помощью Cake.
** ПРАВКИ **
Из статьи, на которую я ссылался, — которая может не быть текущим или рабочим кодом. Я упомянул это как отправную точку для вас, чтобы разработать свой собственный код поведения.
Тип определяется типом класса — и структура, о которой вы говорите, применима только к типу настройки наследования одной таблицы. Убедитесь, что вы выполняете импорт родительского класса, как показано в примерах. IE:
<?php
...
App::import('Model', 'Person');
class Manager extends Person
{
...
}
?>
Комментарии:
1. Я попробовал это, используя простой пример, но все еще не работает. Они говорят, что вы должны использовать атрибут var char ‘type’ в родительской таблице. Таким образом, Cakephp «автоматически» определил бы, к какому подклассу вы обращаетесь. Обязательно ли настраивать вручную, как внешний ключ? :S
2. Как я уже сказал — код, вероятно, не работает. Он очень старый, но это та идея, которая вам нужна. Вы можете просмотреть его и выяснить, что он должен делать, и исправить это для вашей версии cake.
Ответ №5:
Я новичок в CakePHP (как и в случае с недельным опытом), но столкнулся с той же проблемой. Как уже было намекнуто здесь, кажется, что композиция — это наиболее традиционный способ продвижения к расширению модели (как вы упомянули в комментарии, используя Has-A вместо Is-A).
Вот что я пытаюсь и надеюсь, что это сработает для моего относительно простого набора вариантов использования:
//'Super Class'
class Log extends AppModel {
var $name = 'Log';
}
//'Sub Class'
class SharedLog extends AppModel {
var $name = 'SharedLog';
var $hasOne = 'Log';
var $validate = array(
'log_id' => array(
'logRule-1' => array(
'rule' => 'notEmpty',
),
'logRule-2' => array(
'rule' => 'isUnique',
)
)
);
}
Я надеюсь, что это близко к тому, для чего нужен подкласс. Когда вы явно запрашиваете SharedLogs, у вас будет доступ к атрибутам журнала. Если вы сделаете запрос с точки зрения журнала, у вас не будет доступа ни к каким расширенным атрибутам SharedLog (но это имеет смысл, потому что, просматривая коллекцию журналов, вы не будете знать, какие из них являются суперклассом, а какие подклассом).
Я думаю, что переменной validate достаточно для предотвращения сирот и дубликатов в базе данных.
Говоря о базе данных, я пошел на риск и сделал так, чтобы в таблице shared_logs не было столбца id, а вместо этого использовался log_id в качестве первичного ключа. Я хотел бы получить некоторые отзывы об этой настройке, потому что я совершенно новичок в фреймворке и не обладаю тем шестым чувством, когда код «просто кажется неправильным» в этом контексте.
РЕДАКТИРОВАТЬ: Я просто подумал, что, предполагая, что я не совсем ошибаюсь в этом (и мне хотелось бы думать, что это не так), это решение предлагает довольно прямой способ превратить экземпляр суперкласса в экземпляр подкласса. Поскольку журнал не может быть общим до тех пор, пока он не будет создан. Возможно, это просто указывает на то, что я должен был думать о композиции с самого начала.