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? – Charles Koppelman Mar 2 '15 at 17:02
  • Sorry the formatting sucks – Ivan Winzer Mar 2 '15 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. – Charles Koppelman Mar 3 '15 at 16:24
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. – Ivan Winzer Mar 2 '15 at 20:12
  • Hope that was clear.... – Ivan Winzer Mar 2 '15 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(); ) – Ivan Winzer Mar 2 '15 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? – Ivan Winzer Mar 2 '15 at 22:00
  • sorry Additional_Contract_Items__c – Ivan Winzer Mar 2 '15 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 Mar 3 '15 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 Mar 3 '15 at 18:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.