I was waiting for some downtime to dive head-first into this, but that didn't really materialize.
I've just finished answering a similar question though, so this topic is fresh in my mind.
Like I said in my comment, I believe the "tree" resource to be the correct one to use. The documentation on the SObject Tree resource isn't exactly the clearest, but it does mention that you can nest up to 5 levels of child records in a single request.
One thing to note is that when you are using the SObject Tree resource to create records (or just try to create records in general), you do not specify an id for any of the records. The referenceId
here is used by Salesforce to automatically set the appropriate relationship field (this will be important in a bit).
It's not entirely clear from your question what your object hierarchy is, but let's take a look at the example request from the create nested records documentation
{
"records" :[{
"attributes" : {"type" : "Account", "referenceId" : "ref1"},
"name" : "SampleAccount1",
"phone" : "1234567890",
"website" : "www.salesforce.com",
"numberOfEmployees" : "100",
"industry" : "Banking",
"Contacts" : {
"records" : [{
"attributes" : {"type" : "Contact", "referenceId" : "ref2"},
"lastname" : "Smith",
"Title" : "President",
"email" : "sample@salesforce.com"
},{
"attributes" : {"type" : "Contact", "referenceId" : "ref3"},
"lastname" : "Evans",
"title" : "Vice President",
"email" : "sample@salesforce.com"
}]
}
}
// rest of request truncated
]
}
This is for creating an Account and immediately creating a Contact related to the Account.
The big difference between what you have and what this example shows is the label that contains the child records. It's a subtle difference unless you're familiar with parent-child subqueries in SOQL. Your attempt tries to use the name of the child SObject, whereas the documentation uses the child relationship name (Contacts instead of Contact).
The short explanation for why we use the child relationship name is because creating a master-detail or lookup relationship on a child object also causes a special "field" to be created on the parent object. This special "field" holds a List<SObject>
(specifically a List of the child sobject's type), and its API name is the same as the child relationship name that you set when you create the relationship field on the child object.
It's hard to know what your child relationship name is between Credit_Memo__c
and Order_Product__c
, but it's likely Order_Products__r
(the plural, and changing __c to __r). You can check this for yourself by looking at the detail page for your lookup relationship on the Order_Product__c
object.
So, that all said, a well-formed request to accomplish what you're looking to do should look like this (make sure to remove my comments, as JSON doesn't support them)
{
"records":[
{"attributes":{"type":"Credit_Memo__c","referenceId":"ref1"},
"Name":"Test",
// You need to use the relationship name, and __r since it's a custom relationship
"Order_Products__r":{
"records":[
// type name in the attributes here should match the API name of your object
{"attributes":{"type":"Order_Product__c","referenceId":"ref2"},
// Do not specify Ids, but be sure to include any other required fields
},
{"attributes":{"type":"Order_Product__c","referenceId":"ref3"},
// If you want to populate data from your credit memo record, you may
// be able to use @{ref1.<field api name here>}, assuming that it's
// either the Id of your parent object, or one of the fields that
// you set (like "Name" in this example => @{ref1.Name})
// I have, however, not tested this myself
}
]
}
}
]
}
Best Answer
You cannot bind two levels down child relationships.
Your
apex:repeat
binding looks like this:The problem is that
c2g__OwnerCompany__r
is a list. But you're trying to tell the interator to bind to a list within a list:c2g__OwnerCompany__r.c2g__BankAccounts__r
.This is not allowed.
In theory you could do something like:
This would give you the ability to list all children of children.