1

So I have read other responses to the error like mines but nothing seems to fix the issue maybe someone can look at my code and help. I have in my controller class (trying to do an add and delete function for additional items assocaited with a contract). For some reason i keep getting the error: Didn't understand relationship 'Contract__r.Additional_Contract_Item__c' in field path. If you are attempting to use a custom relationship, be sure to append the '_r' after the custom relationship name. Please reference your WSDL........

Can anyone help me figure out why im getting the error what am i missing... Code below:

void contractItems(id id) {
cont = [SELECT Id, Name, Status, ContractNumber, Event__c, Contact__c,
      (SELECT Id, Contract__c, Contract__r.Item_Description__c, Contract__r.Quantity__c, Contract__r.Total__c, 
       Contract__r.Unit_Price__c FROM Contract__r.Additional_Contract_Item__c) FROM Contract
      where id = :id limit 1];

 contractItems = cont.Additional_Contract_Item__c;
}

Full Code:

public with sharing class ContractsController {

public Contract cont { get; private set;}
public Additional_Contract_Item__c[] contractItems { get; private set; }
private ApexPages.StandardController controller;

// constructor, loads the Account and
// any cases associated with it

void contractItems(id id) {
cont = [SELECT Id, Contract__c, Item_Description__c, Quantity__c, Total__c, 
        Unit_Price__c FROM Additional_Contract_Item__c
        where Contract__c = :id];
//Hook caseItems to the query above
contractItems = cont.Additional_Contract_Item__c;
/* contractItems = [SELECT Id, Contract__c, Contract__r.Item_Description__c, Contract__r.Quantity__c, 
                    Contract__r.Total__c, Contract__r.Unit_Price__c 
                    FROM Additional_Contract_Item__c 
                    where Contract__c = : id]; */
}

//Define the id
id contractid;

/* A List Method to delete the Cases assigned*/
public list todelete = new list();

public ContractsController (ApexPages.StandardController c)
{
/* this will kickoff you main page */
controller = c;
/* to get this current Account Id*/
contractid = c.getRecord().id;
/*kick off the init() function*/
init();
}
public ContractsController () {
contractid =
ApexPages.CurrentPage().getParameters().get('id');

init();

}

void init() {
/* load up Cases
basically we defined caseitems up on top, so
when the page loads then caseItems(accountId)
will go through the query and list out the
Items assoicated with it */
contractItems(contractid);  
}

public PageReference save() {
try {
upsert contractItems;
if ( todelete.size() > 0 ) {           
delete todelete;   
}
contractItems(cont.id);
}
catch ( DmlException exc) {
      ApexPages.addMessages(exc);
      return null;
}
return null;
}


/* your Delete functionality*/
public PageReference del() {

 string delname = ApexPages.CurrentPage().getParameters().get('delname');
 system.assert( delname != null );
 integer gone = -1;
 integer i = 0; 

 for ( i=0; i< caseItems.size(); i++ ) { 
 if (contractItems[i].Contract__c== delname) { 
 gone = i;
 } 
 }
 if ( gone >= 0) { 
 todelete.add(caseItems.remove(gone) ); 
 }
return null;
}
public PageReference add() {
// insert a new line, after user clicks Add
Additional_Contract_Item__c ac =  new Additional_Contract_Item__c(
contractid = cont.id
//Subject = 'hello', Status = 'Low',
//Reason = 'Other',Origin='Low'
);
contractItems.add ( ac );
return null;
 }



}
3
  • What is your goal? What is your schema? Commented Mar 2, 2015 at 17:02
  • Sorry the formatting sucks Commented Mar 2, 2015 at 22:43
  • @IvanWinzer Your question was much more on target before. Please revert changes to the older version which just asked about the SOQL. Try to figure out your new problem on your own. If you can't, please post it separately. Commented Mar 3, 2015 at 16:24

2 Answers 2

3

I am going to make some assumptions.

First, I assume that Additional_Contract_Item__c is a custom object that is a "detail" of the Contract object.

Second, I assume tat you want to select all of the Additional_Contract_Item__c records that are related to a single Contract record.

So every master-detail relationship (and every relationship) has two names. One is the relationship from the detail to the master, and one how the master relates to the detail. For instance, in a Parent-Child relationship, to get from the Parent to the Child, you need to access the "Children". To get from the Child to the Parent, you need to access the "Parent".

You seem to be a little confused in how these inner joins work (which is totally reasonable - they're confusing). If I had a Parent__c object, and a Child__c object, with the relationship from Parent__c to Child__c called Children__r, and I wanted all of the children of a parent, I'd do something like this:

SELECT Id, Name, 
      (SELECT Id, 
              Name, 
              Child_Information__c
       FROM Children__r)
FROM Parent__c

To apply this in your case, you'd need to do something like:

SELECT ...,
      (SELECT ...
       FROM Additional_Contract_Items__r)
FROM Contract
WHERE id = :id limit 1

But you need to figure out what the relationship from Contract to Additional_Contract_Item__c is (I am assuming it's called Additional_Contract_Items__r, which would be the default).


However!

I'm not entirely clear why you are even querying on the Contract record. Unless I'm missing something, that's more than you'd need. Since you don't seem to be doing anything with the Contract record itself, you can rethink this query as "I want a set of Additional_Contract_Item__c records that are children of a Contract". Then you can get rid of the join altogether:

SELECT Id, Contract__c, Contract__r.Item_Description__c,
       Contract__r.Quantity__c, Contract__r.Total__c, 
       Contract__r.Unit_Price__c
FROM Additional_Contract_Item__c
WHERE Contract__c = :id

The one last assumption I am making here is that Item_Description__c, Quantity__c, and so on, are fields on the Contract record, not the Additional_Contract_Item__c (in which case the data will be the same in each row). If instead, the fields are on the Additional_Contract_Item__c record, you should delete all the mentions of Contract__r. above.

3
  • Yes Additional_Contract_Items__c is a child object of the Contract object. What I am attempting to do is add or delete rows in a VF page to add additional contract items to a contract. So for instance contract # TXP1003 has 1 additional item and I want to add 2 more I can go to the vf page embedded on the contract object and say add row and enter in the information to create or delete the additional items in the related child object of contract. Commented Mar 2, 2015 at 20:12
  • Hope that was clear.... Commented Mar 2, 2015 at 20:12
  • Ok so below is the full code. I took your advice on using the simplar query which worked. but now im getting a error that says: expecting a left angle bracket, found 'todelete' at line 26 ( public list todelete = new list(); ) Commented Mar 2, 2015 at 22:41
0

If you are trying to bring back the child records on a parent query, you will need to use the plural form. I'm not sure what you specified, but I imagine you need to change the query to :

[SELECT Id, Name, Status, ContractNumber, Event__c, Contact__c, Quantity__c, Total__c, Unit_Price__c, 
      (SELECT Id FROM Additional_Contract_Items__c) FROM Contract
      where id = :id limit 1];

Also, but the parent fields in the parent part of the query.

As Charles points out, if you are just looking for the child records of one contract record you can just query on:

contractItems = [SELECT Id, Contract__c, Contract__r.Item_Description__c, Contract__r.Quantity__c, 
                    Contract__r.Total__c, Contract__r.Unit_Price__c 
                    FROM Additional_Contract_Item__c 
                    where Contract__c = : id];
4
  • So quantity / Total / Unit Price / Contract__c are the fields found on the child object Additional_Items__c. It is a master detail relationship between the parent (Contracts) and the child (Additional Items). So would I still need to do the __r for the relation to the parent? Commented Mar 2, 2015 at 22:00
  • sorry Additional_Contract_Items__c Commented Mar 2, 2015 at 22:02
  • You certainly don't need to include contract in the sub-query since that will be on the parent object (simply the id). Just include the child fields as you would with a regular query (SELECT Id, Total__c, Unit_Price__c FROM Additional_Contract_Items__c)
    – user8560
    Commented Mar 3, 2015 at 18:04
  • But as Charles points out, if you just want child records, you can query on the child record where the parent is the id you have.
    – user8560
    Commented Mar 3, 2015 at 18:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .