Link Multiple field with Primary¶
Sometimes you have a hasMany relationship and need to have the ability to a select primary record among related ones. As example, a Contacts field of the Case entity.
Need to create a
contacts
linkMultiple field with a primary for our custom entity Stock.
Step 1¶
Create (or edit) custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json
:
{
"fields": {
"contacts": {
"type": "linkMultiple",
"view": "custom:views/stock/fields/contacts"
},
"contact": {
"type": "link"
}
},
"links":{
"contact": {
"type": "belongsTo",
"entity": "Contact",
"foreign": "stocksPrimary"
},
"contacts": {
"type": "hasMany",
"entity": "Contact",
"foreign": "stocks",
"layoutRelationshipsDisabled": true
}
}
}
Step 2¶
custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json
{
"links":{
"stocksPrimary": {
"type": "hasMany",
"entity": "Stock",
"foreign": "contact",
"layoutRelationshipsDisabled": true
},
"stocks": {
"type": "hasMany",
"entity": "Stock",
"foreign": "contacts"
}
}
}
Step 3¶
custom/Espo/Custom/Hooks/Stock/AfterSave.php
<?php
namespace Espo\Custom\Hooks\Stock;
use Espo/ORM/Entity;
use Espo/ORM/EntityManager;
class AfterSave
{
public function __construct(private EntityManager $entityManager) {}
public function afterSave(Entity $entity, array $options): void
{
if (!$entity->isAttributeChanged('contactId')) {
return;
}
$contactId = $entity->get('contactId');
$fetchedContactId = $entity->getFetched('contactId');
$relation = $this->entityManager
->getRDBRepository($entity->getEntityType())
->getRelation($entity, 'contacts');
if (!$contactId) {
$relation->unrelateById($fetchedContactId);
return;
}
$relation->relateById($contactId);
}
}
Step 4¶
client/custom/src/views/stock/fields/contacts.js
define(['views/fields/link-multiple-with-primary'], (Dep) => {
return class extends Dep {
primaryLink = 'contact'
}
});
Step 5¶
Run Rebuild.
Step 6¶
Execute an SQL query:
UPDATE stock
JOIN contact_stock
ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
SET stock.contact_id = contact_stock.contact_id