#php #oop #cakephp #models
#php #ооп #cakephp #Модели
Вопрос:
В настоящее время у меня есть две модели: продукт и услуга. Обе используют одну и ту же структуру таблицы и одни и те же методы. Однако, когда я обновляю один метод, мне придется сделать то же самое с другой моделью. И это становится беспорядочным, не говоря уже о том, что я вызываю избыточность, и это не лучшая доступная практика.
Я знаю, что модели могут быть связаны с одной таблицей, поэтому мне просто нужно добавить $useTable = 'stuff'
в модель, и я мог бы добавить type
поле. Однако я не могу понять, как создать «родительскую» модель, поскольку каждая модель расширяет AppModel.
Честно говоря, я почти ничего не знаю об ООП, так что, возможно, я упускаю что-то очень очевидное и простое.
Что бы я сделал, не зная, как расширить двух дочерних элементов (продукт и услугу) на родительский элемент (Материал), было бы что-то вроде:
$this->Stuff->type = 'product';
$products = $this->Stuff->findAvailable();
Но я уверен, что есть гораздо более простой и понятный подход.
Спасибо.
Комментарии:
1. почему вы используете 2 модели, когда у вас там одинаковые методы?
2. @alexdd55 потому что это две разные вещи.
Ответ №1:
Используйте поведение. Как указано в кулинарной книге:
Поведение модели — это способ организовать некоторые функциональные возможности, определенные в моделях CakePHP. Они позволяют нам разделять логику, которая может не иметь прямого отношения к модели, но должна быть там. Предоставляя простой, но мощный способ расширения моделей, модели поведения позволяют нам присоединять функциональность к моделям, определяя простую переменную класса. Вот как поведение позволяет моделям избавиться от всего лишнего веса, который может не быть частью бизнес-контракта, который они моделируют, или который также необходим в разных моделях и затем может быть экстраполирован.
http://book.cakephp.org/view/1071/Behaviors
Ссылка должна дать вам довольно хорошее представление о том, с чего начать.
Ответ №2:
Вы в основном используете наследоваемость и расширяемость:
Расширяемый: [ссылка удалена в соответствии с моим статусом новичка. Это в файле ниже из gitub]
Наследуемый: http://bakery.cakephp.org/articles/taylor.luk/2008/10/22/inheritable-behavior-missing-link-of-cake-model
Которые были включены в:https://github.com/CakeDC/utils/blob/master/models/behaviors/inheritable.php
Я только что использовал этот же метод (также для продуктов и сервисов). На самом деле, у меня есть разные поля для каждого, общие поля, а затем подтипы (2 класса продуктов и 3 класса услуг), поэтому я создал модель предложения с таблицей предложений, которая выглядит следующим образом:
CREATE TABLE `offers` (
`id` int(11) NOT NULL AUTO_INCREMENT, //common
`carrier_id` int(11) DEFAULT NULL, //common
`category_id` int(11) DEFAULT NULL, //common
`name` varchar(255) DEFAULT NULL, //common
`description` longtext, //common
`type` ENUM('Product', 'Service') not null default 'Product',
`sku` varchar(255) DEFAULT NULL, //product
`make` varchar(255) DEFAULT NULL, //product
`model` varchar(255) DEFAULT NULL, //product
`listprice` decimal(9,2) DEFAULT NULL, //product
`soc_code` varchar(255) DEFAULT NULL, //service
`unit` varchar(255) DEFAULT NULL, //service
`units` int(11) DEFAULT NULL, //service
`mrc` decimal(9,2) DEFAULT NULL, //service
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `carrier_id` (`carrier_id`),
KEY `category_id` (`category_id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Тогда моя предлагаемая модель выглядит следующим образом:
<?php
class Offer extends AppModel {
public $name = 'Offer';
public $useTable = 'offers';
public $displayField = 'name';
public $belongsTo = array(
'Carrier' => array(
'className' => 'Carrier',
'foreignKey' => 'carrier_id',
),
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id',
)
);
С моделью продукта:
<?php
App::import('Model', 'Offer');
class Product extends Offer {
public $name = 'Product';
public $useTable = 'offers';
public $displayField = 'name';
public $actsAs = array('utils.inheritable');
(Сервис практически идентичен).
Затем вы создаете все свои методы в рамках модели предложения, и в этих моделях будет существовать только все, что уникально подходит для продуктов или услуг подклассов.
Я надеюсь, что это поможет, если вы еще не нашли решение.
Комментарии:
1. Дизайн вашей базы данных очень плох. Слишком много нулевых значений. Я бы рекомендовал вам иметь таблицу предложений с общими атрибутами, таблицы продуктов и услуг с атрибутами, связанными только с ними, плюс внешние ключи к таблице предложений.
Ответ №3:
Поместите методы, которые используют обе модели, в вашу AppModel:
Этот промежуточный класс, AppModel, пуст, и если вы не создали свой собственный, он берется из папки /cake /. Переопределение AppModel позволяет вам определить функциональность, которая должна быть доступна для всех моделей в вашем приложении. Для этого вам нужно создать свою собственную app_model.php файл, который находится в корне папки /app /.
Ваши модели продуктов и услуг расширяют AppModel. Это означает, что для них доступны все методы из AppModel.