Salesforce.comのApexプログラミング言語を学習しようとしています。ここに、JasonOuelletteの著書「DevelopmentwiththeForce.comPlatform」からのコードの例があります。私はまだ基本を学んでいるので、我慢してください。このコードをコンテキストに入れるために、本全体に渡るServices Managerサンプルアプリケーションがあり、タイムカードに有効な割り当てがあることを確認するために作成されたApexトリガーデバイスを調べています。割り当ては、リソースが特定の期間プロジェクトに配置されていることを示すレコードです。コンサルタント(別名リソース)は、プロジェクトと彼または彼女が作業を許可されている期間についてのみタイムカードを入力できます。Resource_cは、Assignment_cオブジェクトとTimecard_cオブジェクトの両方の親です。
これが、トリガーと対応するapexクラスに対して提供されるコードです。私はそれを分解し、その論理を理解するために1行ずつコメント/質問しようとしています。しかし、私はまだここでいくつかの基本を欠いています、私がこれを解読するのを手伝ってください。
5-57トリガー
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);
}
}
}
}
ご協力ありがとうございました。