Intereting Posts

cakephp3 связывает одну таблицу с несколькими таблицами в зависимости от типа

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

Policies item_id item_type 

и который ссылается на разные таблицы в зависимости от значения поля «item_type», например:

 item_type = car then link to the cars table item_type = house then link to the houses table item_type = business then link to the businesses table and so on... 

Я могу сделать это самостоятельно с помощью php и mysql, но я хочу знать, как это сделать, используя связи и привязку таблиц CakePHP. Я попытался использовать сквозной вариант и таблицу отношений, но это не то же самое. Есть идеи? или если таблица отношений является единственным способом сделать это, тогда скажите, пожалуйста, как это сделать.

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

Первое, что нужно сделать, это создать поведение. Это позволит вам включить любой класс таблицы в приложении, чтобы к нему была привязана политика.

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

 namespace App\Model\Behavior; use Cake\Event\Event; use Cake\ORM\Behavior; use Cake\ORM\Query; class PolicyBehavior extends Behavior { public function initialize(array $config) { parent::initialize($config); $this->_table->hasMany('Policies', [ 'className' => 'Policies', 'foreignKey' => 'table_foreign_key', 'bindingKey' => 'id', 'conditions' => ['table_class' => $this->_table->registryAlias()], 'propertyName' => 'policies' ]); } public function beforeFind(Event $event, Query $query, \ArrayObject $options, $primary) { $query->contain(['Policies']); return $query; } } 

Поэтому в методе initialize нам нужно создать отношение к таблице, к которой мы привязали поведение. Это создаст связь с Table hasMany Policies , что означает, что любой элемент вашей системы может иметь много политик. Вы можете обновить эту взаимосвязь, чтобы она соответствовала тому, как вы работаете.

Вы можете видеть, что существует ряд опций, определенных в отношении. Они важны, поскольку они связывают элементы таблиц вместе. Таким образом, table_foreign_key – это поле в таблице policies db, используемой для хранения primaryKey связанного элемента. Поэтому, если вы прикрепляете политику к автомобилю, это будет Car.id bindingKey – это ключ, используемый в таблице Policy для присоединения.

Чтобы фильтровать различные типы вложений, вам нужно table_class поле table_class в таблице policies db. Это будет имя присоединенного класса таблицы. Итак, Cars , Cats , Houses и т. Д. Тогда мы можем использовать это в условиях, поэтому все, что тянет основной класс таблицы, автоматически фильтрует соответствующие Policies для соответствия.

Я также настроил propertyName , это означает, что любой элемент, который вы ищете, который содержит Policies будет иметь свойство entity, называемое policies с соответствующими данными внутри.

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

Итак, как мы используем это новое поведение? Просто прикрепите его так же, как и любое другое поведение, и все. $this->addBehavior('Policy') .

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

Для ясности ваша схема таблиц policies будет необходима, как минимум.

 policies.id policies.table_class VARCHAR(255) policies.table_foreign_key INT(11)