所以这是我的问题。 我需要将保险单与保险财产/项目联系起来。现在,从汽车政策到房屋或商业的细节差别很大。所以我想做的是在政策表
上有类似的东西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的表关系和链接的正确方法。我尝试使用通过选项和关系表,但它不一样。有任何想法吗?或者如果关系表是唯一的方法,请告诉我如何请。
答案 0 :(得分:4)
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)