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.id
。 bindingKey
是策略 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)
这就是我的问题。 我需要 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.id
。 bindingKey
是策略 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)