dongxianshuai8927 2015-08-11 22:28
浏览 30
已采纳

cakephp3根据类型将一个表链接到多个表

So here's my problem. I need to link an insurance policy to the insured property/item. Now the details vary greatly from car policy to a house or business one. So what I want to do is have something like this on the policies table

Policies
item_id
item_type

and that links to different tables depending on the value of the field "item_type" for example:

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...

I can do that on my own with php and mysql but I want to know the proper way to do it using CakePHP's table relationships and linking. I tried using the through option and a relationship table but it's not the same. Any ideas? or if a relationship table is the only way to do it then tell me how please.

  • 写回答

1条回答 默认 最新

  • doudieyou5209 2015-10-06 08:54
    关注

    This is actually a lot simpler than it first appears. I've done this a few times so I'll detail the technique that I use.

    The first thing to do is create a behavior. This will allow you to enable any Table class in your application to have a policy attached to it.

    The behavior is very simple. I've changed it to match your example, as I understand it. I'll talk through it after the code.

    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;
        }
    }
    

    So the in the initialize method we need to create a relationship to the table we attached the behaviour to. This will create a Table hasMany Policies relationship, meaning that any item in your system can have many policies. You can update this relationship to match how you're working.

    You can see that there are a number of options defined in the relationship. These are important, as they link the tables items together. So the table_foreign_key is a field in your policies db table used to store the primaryKey of the related item. So if you're attaching a Policy to a Car, this would be the Car.id. The bindingKey is the key used in the Policy table to join on.

    In order to filter the different types of attachments, you need the table_class field in your policies db table. This will be the name of the attached table class. So Cars, Cats, Houses etc. Then we can use this in the conditions, so anything pulling the primary table class will automatically filter the related Policies to match.

    I've also configured the propertyName, this means that any item you look for which contains Policies will have an entity property called policies with the related data inside.

    The last function in the behaviour is the beforeFind, this just ensures that whenever you look for the primary table class, you always return the related policies, you don't have to use this if you don't want to, but I found it handy to always have the related data in my use-case.

    So then, how do we use this new behaviour? Just attach it like you would any other behaviour, and that's it. $this->addBehavior('Policy').

    Be aware
    This just reads data, you'll need to ensure that you save the table alias, and the foreignKey into the related table when creating new items.

    Just for clarity, your policies table schema will need, at a minimum.

    policies.id
    policies.table_class VARCHAR(255)
    policies.table_foreign_key INT(11)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用