В Salesforce связи между объектами играют решающую роль в организации и соединении данных. Одним из таких отношений является отношение «Мастер-Деталь», которое обеспечивает прочную связь между двумя объектами, при этом «главный» объект контролирует определенное поведение и характеристики «детального» объекта. В этой статье блога мы рассмотрим концепцию отношений Master-Detail в Salesforce и углубимся в различные методы их реализации и использования в вашей организации Salesforce.
Метод 1. Определение связи «Основной-Детали» в Salesforce
Чтобы установить связь «Основной-Деталь», необходимо определить ее в схеме объекта. Это можно сделать через меню настройки Salesforce или с помощью API метаданных. Ниже приведен пример определения связи «Основной-Детали» между двумя настраиваемыми объектами «Учетная запись» и «Возможная сделка» с использованием кода Apex:
// Define a Master-Detail relationship between Account and Opportunity
// Create a custom field on the Opportunity object
// Set the Account object as the master and enforce cascading deletes
// Apex code
Schema.SObjectType opportunityObj = Schema.getGlobalDescribe().get('Opportunity');
Schema.DescribeSObjectResult opportunityDescribe = opportunityObj.getDescribe();
// Create a custom field on Opportunity to establish the Master-Detail relationship
Schema.SObjectField accountField = opportunityDescribe.fields.getMap().get('Account__c');
if (accountField == null) {
    Schema.SObjectType accountObj = Schema.getGlobalDescribe().get('Account');
    Schema.DescribeSObjectResult accountDescribe = accountObj.getDescribe();
    accountField = accountDescribe.fields.getMap().get('Id');
    // Create the custom field on Opportunity
    Schema.SObjectField customField = new Schema.FieldSetMember(accountField, null, false);
    Schema.SObjectField[] fields = new Schema.SObjectField[] { customField };
    Schema.SObjectField[] fieldsWithRelationship = new Schema.SObjectField[] { customField };
    opportunityDescribe.fields.getMap().put('Account__c', customField);
    opportunityDescribe.fields.getMap().put('Account', customField);
    opportunityDescribe.fields.getMap().put('AccountId', customField);
    // Set the Account object as the master
    opportunityDescribe.fields.getMap().get('Account__c').setReferenceTo(new Schema.SObjectType[] { accountObj });
    opportunityDescribe.fields.getMap().get('Account').setReferenceTo(new Schema.SObjectType[] { accountObj });
    opportunityDescribe.fields.getMap().get('AccountId').setReferenceTo(new Schema.SObjectType[] { accountObj });
    // Enforce cascading deletes
    opportunityDescribe.fields.getMap().get('Account__c').setCascadeDelete(true);
    opportunityDescribe.fields.getMap().get('Account').setCascadeDelete(true);
    opportunityDescribe.fields.getMap().get('AccountId').setCascadeDelete(true);
}
Метод 2: использование полей сводной сводки
Одной из мощных функций отношений «Основная-подробная информация» является возможность использования полей сводной сводки. Эти поля позволяют выполнять вычисления с дочерними записями и отображать результаты в основной записи. Допустим, у вас есть связь «Основной-Детали» между объектами «Счет» и «Возможная сделка», и вы хотите отобразить общую сумму всех связанных возможностей в записи учетной записи. Этого можно добиться с помощью поля сводной сводки.
// Create a Roll-Up Summary field on the Account object to calculate the total opportunity amount
// Apex code
List<Account> accountsToUpdate = new List<Account>();
for (Opportunity opp : [SELECT AccountId, Amount FROM Opportunity]) {
    if (opp.AccountId != null) {
        Account acc = new Account(Id = opp.AccountId);
        acc.Total_Opportunity_Amount__c += opp.Amount;
        accountsToUpdate.add(acc);
    }
}
update accountsToUpdate;
Метод 3: использование триггеров для пользовательской логики
С помощью отношений «Основная-Детализация» вы можете использовать триггеры для выполнения пользовательской логики, когда в подробных записях происходят определенные события. Например, предположим, что у вас есть связь «Основная-Сведения» между объектами «Учетная запись» и «Контакт», и вы хотите автоматически обновлять поле в записи учетной записи при каждом создании или удалении контакта. Этого можно добиться с помощью триггеров.
// Write a trigger on the Contact object to update a field on the Account object
// Apex code
trigger ContactTrigger on Contact (after insert, after delete) {
    Set<Id> accountIds = new Set<Id>();
    if (Trigger.isInsert) {
        for (Contact contact : Trigger.new) {
            if (contact.AccountId != null) {
                accountIds.add(contact.AccountId);
            }
        }
    } else if (Trigger.isDelete) {
        for (Contact contact : Trigger.old) {
            if (contact.AccountId != null) {
                accountIds.add(contact.AccountId);
            }
        }
           }
// Update the field on the Account object
    List<Account> accountsToUpdate = [SELECT Id, Last_Contact_Date__c FROM Account WHERE Id IN :accountIds];
    for (Account acc : accountsToUpdate) {
        // Perform custom logic here
        acc.Last_Contact_Date__c = Date.today();
    }
    update accountsToUpdate;
}
Отношения «Основной-Детальный» в Salesforce предоставляют мощный способ установления связей между данными и управления поведением между объектами. В этой статье мы рассмотрели различные методы реализации и использования связей «Основная-Детализация», включая определение связей, использование полей сводной сводки и использование триггеров для пользовательской логики. Понимая и используя потенциал взаимоотношений «главный-подробный», вы сможете повысить функциональность и эффективность своей организации Salesforce.