It isn't working because the Asset
Id field is null in the before insert
context.
Records do not have Ids until after insert
.
Beyond that, you're updating an Account
record in your Asset
trigger, but you aren't performing a DML update for those Accounts
.
You can only avoid DML in triggers in before
contexts on the same SObject (so in your Asset
trigger, you can only avoid DML for the Asset
records that caused the trigger to fire).
If you need to update other SObjects (like Account
), Salesforce recommends using an after
trigger.
+edit:
After taking a third look at your trigger, I think there's still more work that you need to do. Right now, you're updating the Asset__c
field of each Account
that you queried multiple times (meaning all of the Accounts
you queried will have Asset__c
set to whichever Asset
record happens to be the last on in Trigger.new
).
I doubt that's what you intend to have happen. You could fix things (and get rid of your nested loop) by putting the results of your Account
query into a map (instead of a list), but you could completely avoid both the nested loop and your query for Accounts
.
You could do this by using the following pattern (which you'll need to adjust to your particular situation).
// Declare a list to hold records that we want to update
List<OtherObject__c> myOtherObjectsToUpdate = new List<OtherObject__c>();
for(MyObject__c myObj :Trigger.new){
// Each SObject has a constructor that allows you to specify name-value pairs
// for fields.
// You can use this to set the Id field (which is otherwise read-only).
// Doing so allows you to update a record without the need to query for it first.
myOtherObjectsToUpdate.add(new OtherObject__c(
Id = myObj.OtherObject__c, // just like all other method calls, name = value pairs are separated by commas in the constructor
someLookupField__c = myObject.Id // you can also set other writable fields in the constructor
));
}
update myOtherObjectsToUpdate;