场景描述:开发中经常遇到记录一旦创建,其中的某个字段就不允许被修改的需求,以保证记录的安全性,以下提供两种解决方案。
方案一:使用Validation Rules实现
Sample:当记录第一次被保存后,就不允许用户修改其中某个字段-isCheck:
Validation Rule:
最终效果:
方案二:使用Trigger实现
Sample:比较old和new fields是否相同:oldMap适用于Update/Delete trigger
for(Opportunity opp : Trigger.new){
//Create an old and new map so that we can compare values
Opportunity oldOpp = Trigger.oldMap.get(opp.ID);
Opportunity newOpp = Trigger.newMap.get(opp.ID);
//Retrieve the old and new Reseller Email Field
string oldResellerEmail = oldOpp.Reseller_Email__c;
string newResellerEmail = newOpp.Reseller_Email__c;
//If the fields are different, the email has changed
if(oldResellerEmail != newResellerEmail){
oppIDs.put(opp.Id,opp.Reseller_Email__c);
}
}
注意:在实际运用时,可能会出现下图错误:
我们仅需改进如下:
((Map<Id, Lead>)Trigger.oldMap).get(l.Id).OwnerId <> l.OwnerId
【Trigger项目实战 - after insert/update/delete/undelete】:
项目中有如下需求:A和B对象为lookup关系,其中A为父,B为子,目前想将B的Name字段拼接到A的某字段上,Code如下:
public class TradingAccountTriggerFunction {
public static void joinLoginToAccount(Set<String> accSet) {
Savepoint sp = Database.setSavepoint();
try{
List<Account> accs = [SELECT Id, Trading_Account_Login__c, (SELECT Id, Name FROM MT4_Accounts__r ORDER BY LastModifiedDate)
FROM Account
WHERE Id IN :accSet];
for(Account acc : accs) {
acc.Trading_Account_Login__c = '';
for(Integer i = 0; i < acc.MT4_Accounts__r.size(); i++) {
acc.Trading_Account_Login__c += (i == acc.MT4_Accounts__r.size() - 1) ? acc.MT4_Accounts__r[i].Name : acc.MT4_Accounts__r[i].Name + ';';
System.debug(acc.Trading_Account_Login__c);
}
}
update accs;
}catch(Exception e) {
System.debug(e.getMessage());
Database.rollback(sp);
}
}
}
public class TradingAccountTriggerHandler extends TriggerHandler{
//handle before insert logic
public override void beforeInsert(){}
//handle before update logic
public override void beforeUpdate(){}
//handle before delete logic
public override void beforeDelete(){}
//handle after insert logic
public override void afterInsert(){
System.debug('go into after insert logic.');
Set<String> accIdSet = new Set<String>();
for(MT4_Accounts__c tAcc : (List<MT4_Accounts__c>)Trigger.new) {
accIdSet.add(tAcc.Account__c);
}
if(accIdSet.size() > 0) {
TradingAccountTriggerFunction.joinLoginToAccount(accIdSet);
}
}
//handle after update logic
public override void afterUpdate(){
System.debug('go into after update logic.');
Set<String> accIdSet = new Set<String>();
for(MT4_Accounts__c tAcc : (List<MT4_Accounts__c>)Trigger.new) {
if(((Map<Id, MT4_Accounts__c>)Trigger.oldMap).get(tAcc.Id).Name <> tAcc.Name)
accIdSet.add(tAcc.Account__c);
}
if(accIdSet.size() > 0) {
TradingAccountTriggerFunction.joinLoginToAccount(accIdSet);
}
}
//handle after delete logic
public override void afterDelete(){
System.debug('go into after delete logic.');
Set<String> accIdSet = new Set<String>();
for(MT4_Accounts__c tAcc : (List<MT4_Accounts__c>)Trigger.old) {
accIdSet.add(tAcc.Account__c);
}
if(accIdSet.size() > 0) {
TradingAccountTriggerFunction.joinLoginToAccount(accIdSet);
}
}
//handle after undelete logic
public override void afterUndelete(){
System.debug('go into after undelete logic.');
Set<String> accIdSet = new Set<String>();
for(MT4_Accounts__c tAcc : (List<MT4_Accounts__c>)Trigger.new) {
accIdSet.add(tAcc.Account__c);
}
if(accIdSet.size() > 0) {
TradingAccountTriggerFunction.joinLoginToAccount(accIdSet);
}
}
}