6

I have created a many to many relationship between two objects, A and B, using a junction object. That works fine, and the related lists show up on A and B with standard layout pages. Is it possible to display fields from object A on object B using this relationship, i.e. using the junction object? How would I reference the fields from A in B on a Visualforce page? Where can I find the name of the relationship?

2 Answers 2

7

In my org, I have three objects, Position__c (Master object), Employment_Website__c (Master Object) and Job_Posting__c (Junction object between the two).

If I wanted to display all related Employment Website data for a Position object through a Visualforce page, I would use a page with a standard controller for the Position object. On this page I would loop through the related job posting child objects, and then for each row reference the parent employment website through the parent relationship api name.

Here is an example:

<apex:page StandardController="Position__c">
  <apex:sectionHeader title="Position: {!Position__c.Name}"/>
  <apex:pageBlock title="Employment Websites">
      <apex:pageBlockTable value="{!Position__c.Job_Postings__r}" var="jobPost">
          <apex:column value="{!jobPost.Employment_Website__r.Name}"/>
          <apex:column value="{!jobPost.Employment_Website__r.Web_Address__c}"/>
          <apex:column value="{!jobPost.Employment_Website__r.Price_Per_Post__c}"/>
      </apex:pageBlockTable>
  </apex:pageBlock>
</apex:page>

I have used a page block table to show the data, but this could be a repeat, or just a plain data table too. If you have a custom controller, you will have to retrieve the fields using some relational SOQL beforehand, but the relationship references remain the same.

The relationship api names are defined on the master-detail field detail page, found on the custom field list on the junction object definition page. Just don't forget to append '__r' and the end of the relationships (replacing '__c' if it exists).

enter image description here

enter image description here

Hope that helps!

1

In your VF page where you'd like to present object B and related list of A objects, you would need to fetch list of related A objects, but queried with the fields you would like to display.

E.g. let's say you have a ObjectB.page:

<apex:page standardController="B__c" extensions="ObjectBControllerExt" recordSetVar="JunctionObjName">
    <h1>Details for {!objB.Name}</h1>

    <apex:form>
        <apex:pageBlockTable value="ABjunctions" var="ABjunc">
            <apex:column value="ABjunc.A__r.Id" />
            <apex:column value="ABjunc.A__r.Name" />
            <apex:column value="ABjunc.A__r.DateCreated" />
        </apex:pageBlockTable>
    <apex:form>
</apex:page>

You would have to form your controller to resemble something like:

public with sharing class ObjectBControllerExt {

    public B__c objB { get; set; }
    public List<A_B__c> ABjunctions { get; set; }

    public ObjectBControllerExt(ApexPages.StandardController controller)
    {
        objB = (B__c)stdController.getRecord();

        ABjunctions = [SELECT Id, Name, A__c, A__r.Id, A__r.Name, A__r.Id FROM A_B__c WHERE B__c = :objB];
    }
}


Written in rush, but I think it should work. On a side note, even better solution would be to use an inner class as proxy object - in your case, in the controller constructor you could fetch all the junction objects, iterate over the collection and create fully customized list to suit your needs:

public List<MyInnerClass> listOfAobjects { get; set; }

public ObjectBControllerExt(ApexPages.StandardController controller)
{
    objB = (B__c)stdController.getRecord();

    ABjunctions = [SELECT Id, Name, A__c, A__r.Id, A__r.Name, A__r.Id FROM A_B__c WHERE B__c = :objB];

    listOfAobjects = new List<MyInnerClass>();
    for(APN_SRF__c abJunc : ABjunctions) {
        listOfAobjects.add(new MyInnerClass(abJunc.A__c));
    }
}

public class MyInnerClass {
    public string aName { get; set; }
    public string aProp1 { get; set; }
    public string aProp2 { get; set; }
    ...

    public MyInnerClass(A__c objectA) {
        this.aName = objectA.Name;
        ...
    }
}


Of course, in case you would use the solution with inner class as 'proxy object', you'd need to update the bindings in the VF page accordingly. Hope you got the big picture...

You must log in to answer this question.

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