+ Start a Discussion
Scott0987Scott0987 

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

Best Answer chosen by Admin (Salesforce Developers) 
kibitzerkibitzer

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

SalesForce DummySalesForce Dummy

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;

}

kibitzerkibitzer

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

 

This was selected as the best answer
SalesForce DummySalesForce Dummy

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.

 

kibitzerkibitzer

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