Salesforce.com의 Apex 프로그래밍 언어를 배우려고하고 있으며 Jason Ouellette가 저술 한 "Force.com 플랫폼 개발"책에서 나온 몇 가지 코드 예제를 보았습니다. 나는 여전히 기초를 배우고 있으므로 나와 함께 견뎌주십시오. 컨텍스트에서이 코드를 사용하려면 책 전체에 걸쳐있는 서비스 관리자 샘플 응용 프로그램이 있으며 타임 카드에 유효한 할당이 있는지 확인하기 위해 작성한 Apex 트리거 장치를 검사하고 있습니다. 과제는 특정 기간 동안 프로젝트에 자원이 배치되었음을 나타내는 기록입니다. 컨설턴트 (일명 자원)는 프로젝트 및 시간 동안 만 근무 시간 카드를 입력 할 수 있습니다. Resource_c는 Assignment_c 및 Timecard_c 개체의 부모입니다.Elementary Apex 트리거 논리 고장
그래서 여기에 트리거와 해당 정점 클래스에 대한 코드가 있습니다. 나는 그것의 논리를 이해하기 위해 그것을 한 줄 한 줄씩 주석을 달아서 시도하고있다. 그러나, 나는 아직도 여기에 몇 가지 기본을 놓치고있다, 이것을 해독하는 데 자유롭게 느끼십시오.
5-57 트리거 (Trigger)
trigger validateTimecard on Timecard__c (before insert, before update) {
TimecardManager.handleTimecardChange(Trigger.old, Trigger.new);
// TheApexClass.methodThatDoesWork(variable, variable)
// So there are 2 parameters which are 2 lists, Trigger.old and Trigger.new.
// Which means, when this method is called it needs these 2 lists
// to process it's block of code, right?
// Why are they called Trigger.old, Trigger.new? Does the order of variables matter?
}
5-58 - Apex의 클래스 - 트리거를 대신하여 근무 시간 기록표를 검증하는 작업을 수행합니다.
public class TimecardManager {
public class TimecardException extends Exception {}
public static void handleTimecardChange(List<Timecard__c> oldTimecards, List<Timecard__c> newTimecards) {
// Identifying 2 lists of Timecards as parameters, oldTimecards and newTimecards
// within the class. How is this associated with the trigger parameters
// that were seen in the trigger above. Are they the same parameters with
// different names? Why are they named differently here? Is it better to
// write the trigger first, or the apex class first?
Set<ID> resourceIds = new Set<ID>(); // making a new set of primitive data type ID called resourceIds
for (Timecard__c timecard : newTimecards) {
// This for loop assigns the timecard variable record to the list of newTimecards
// and then executes the block of code below for each.
// The purpose of this is to identify all the resources that have timecards.
resourceIds.add(timecard.Resource__c);
// It does this by adding the Timecard_c's relationship ID from each parent record Resource_c to the resourceIds set.
// For clarification, Resource_c is a parent to both
// Assignment_c and Timecard_c objects. Within the Timecard_c object, Resource_c
// is a Master-Detail data type. Is there a relationship ID that is created
// for the relationship between Resource_c and Timecard_c?
}
List<Assignment__c> assignments = [ SELECT Id, Start_Date__c, End_Date__c, Resource__c FROM Assignment__c WHERE Resource__c IN :resourceIds ];
// The purpose of this is to make a list of selected information from Assignments_c that have resources with timecards.
if (assignments.size() == 0) {
// If there isn't a Resource_c from Assignments_c that matches a Resource_c that has a Timecard_c,
throw new TimecardException('No assignments'); // then an exception is thrown.
}
Boolean hasAssignment; // creation of a new Boolean variable
for (Timecard__c timecard : newTimecards) { // so for every newTimecards records,
hasAssignment = false; // set Boolean to false as default,
for (Assignment__c assignment : assignments) { // check through the assignments list
if (assignment.Resource__c == timecard.Resource__c && // to make sure the Resources match,
timecard.Week_Ending__c - 6 >= assignment.Start_Date__c && // the end of the timecard is greater than the assignment's start date,
timecard.Week_Ending__c <= assignment.End_Date__c) { // and the end of the timecard is before the assignment's end date.
hasAssignment = true; // if these all 3 are correct, than the Timecard does in fact have an assignment.
break; // exits the loop
}
}
if (!hasAssignment) { // if hasAssignment is false then,
timecard.addError('No assignment for resource ' + // display an error message
timecard.Resource__c + ', week ending ' +
timecard.Week_Ending__c);
}
}
}
}
감사합니다.