You need to sign in to do that
Don't have an account?
Scott0987
sObject lookup based on a field from a second sObject.
I am very new to Apex so please forgive me if this is a stupid question.
I have 2 custom salesforce objects. s1 and s2. s2 has a field that is unique to both it and s1. It is called identifier. I am creating a trigger that will update the fields on s2 when s1 is updated. What I cannot figure out how to do is inside the trigger apex to find the id of s2 based on the identifier field of s1.
Thanks
First - no offense, but please ignore the previous response - it has SOQL inside a loop which is always a bad idea.
Now, based on what you describe, you're looking for something like this (the following is psudocode - a rough outline of code that should work, but has not been tested)
trigger sometrigger on S1 (after insert)
{
// Get a list of the identifiers
List<String> identifiers = new List<String>(); // I'm assuming identier is a string
for(S1 obj: trigger.new) identifiers.add(s1.identifier);
// Now query for S2 - Be aware of limit issues if you have over 100K S2 objects
List<S2> alls2s = [Select ID, identifier, your list of fields, from S2 where identifier in :identifiers];
// Now create a map from identifier to S2
Map<String, S2> s2map = new Map<String, S2>();
for(S2 obj: alls2s) s2map.put(s2.identifier, s2);
// Now do your updates
for(S1 s1obj: trigger.new)
{
S2 s2toupdate = s2map.get(s1obj.identifier);
// Modify the S2 object fields here
}
update alls2s;
}
In practice, you should actually place the functional code inside of a class - but that's another story.
This is a common bulk compatible design pattern for handling updates of related records. It will work well with ID based lookups as well.
My old math teacher said there is no such thing as a stupid question - the only stupid people are the ones who don't ask questions.
Dan
All Answers
I'm pretty sure this would work.
//Loop through trigger records
For(s1 outerObject : trigger.new)
{
//Get the identifier value from s1
string ooID = outerObject.Identifier;
//Create a s2 object and populate it with Id based on the query.
s2 insideObject = new s2()
s2 =[Select Id from S2 Where Identifier =: ooID limit 1];
string s2ID = s2.Id;
}
First - no offense, but please ignore the previous response - it has SOQL inside a loop which is always a bad idea.
Now, based on what you describe, you're looking for something like this (the following is psudocode - a rough outline of code that should work, but has not been tested)
trigger sometrigger on S1 (after insert)
{
// Get a list of the identifiers
List<String> identifiers = new List<String>(); // I'm assuming identier is a string
for(S1 obj: trigger.new) identifiers.add(s1.identifier);
// Now query for S2 - Be aware of limit issues if you have over 100K S2 objects
List<S2> alls2s = [Select ID, identifier, your list of fields, from S2 where identifier in :identifiers];
// Now create a map from identifier to S2
Map<String, S2> s2map = new Map<String, S2>();
for(S2 obj: alls2s) s2map.put(s2.identifier, s2);
// Now do your updates
for(S1 s1obj: trigger.new)
{
S2 s2toupdate = s2map.get(s1obj.identifier);
// Modify the S2 object fields here
}
update alls2s;
}
In practice, you should actually place the functional code inside of a class - but that's another story.
This is a common bulk compatible design pattern for handling updates of related records. It will work well with ID based lookups as well.
My old math teacher said there is no such thing as a stupid question - the only stupid people are the ones who don't ask questions.
Dan
Kibitzer, no offense taken.
Can you tell me how the update statement works in your code?
update alls2s;
I don't see anywhere in the code where you update the list. I see you updating the S2 object but not the list directly.
Sure - it is a bit subtle.
The trick is to realize that when you have an object in a list or a map, the list or a map contains a pointer to the object.
So, when you retrieve the S2 object using the query:
List<S2> alls2s = [Select ID, identifier, your list of fields, from S2 where identifier in :identifiers];
That list contains all of the S2 objects.
When you build the map:
Map<String, S2> s2map = new Map<String, S2>();
for(S2 obj: alls2s) s2map.put(s2.identifier, s2);
The map contains contains pointers to the S2 objects - the same ones pointed to by alls2s. Adding them to the map doesn't change the fact that the same object is also in the alls2s list.
So when you use the map to get a copy of each S2 object, and modify that object. you're modifying the object itself - but again not changing the fact that the same object effectively "exists" in both the s2map and alls2s list.
So when it's time to update the S2 objects that were modified, you can just update alls2s.
You could also do:
update s2map.values();
Dan