cakephp3 link 一个 table 到多个 table 取决于类型

cakephp3 link one table to multiple tables depending on type

这就是我的问题。 我需要 link 一份保险单给被保险人 property/item。现在,从汽车政策到房屋或企业政策,细节差异很大。所以我想做的是在政策上有这样的东西 table

Policies
item_id
item_type

并且 links 到不同的 tables 取决于字段的值 "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 的 table 关系和 linking 的正确方法.我尝试使用 through 选项和关系 table 但它不一样。有任何想法吗?或者如果一段关系 table 是唯一的方法,请告诉我怎么做。

这实际上比最初看起来要简单得多。我已经这样做了几次,所以我将详细介绍我使用的技术。

首先要做的是创建一个行为。这将允许您在应用程序中启用任何 Table class 以附加策略。

行为非常简单。据我了解,我已将其更改为与您的示例相匹配。码完我再说。

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 的关系。这将创建一个 Table hasMany Policies 关系,这意味着您系统中的任何项目都可以有多个策略。您可以更新此关系以匹配您的工作方式。

您可以看到关系中定义了多个选项。这些很重要,因为它们 link table 项放在一起。所以 table_foreign_key 是你的 policies db table 中的一个字段,用于存储相关项目的主键。因此,如果您将政策附加到汽车,这将是 Car.idbindingKey 是策略 table 中用于加入的密钥。

为了过滤不同类型的附件,您需要 policies 数据库 table 中的 table_class 字段。这将是附件的名称 table class。所以 Cars, Cats, Houses 等。然后我们可以在条件中使用它,所以任何拉动主要 table class 的东西都会自动过滤相关的 Policies 匹配。

我还配置了 propertyName,这意味着您查找的任何包含 Policies 的项目都会有一个名为 policies 的实体 属性 以及相关里面的数据。

行为中的最后一个函数是 beforeFind,这只是确保无论何时查找主要 table class,您总是 return 相关 policies,如果你不想,你不必使用它,但我发现在我的用例中总是有相关数据很方便。

那么,我们如何使用这个新行为呢?就像附加任何其他行为一样附加它,仅此而已。 $this->addBehavior('Policy').

注意
这只是读取数据,您需要确保在创建新项目时将 table 别名和 foreignKey 保存到相关的 table 中。

为清楚起见,您的 policies table 架构至少需要。

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