Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Getting fields from has_one ID through has_many


Go to End


2 Posts   2338 Views

Avatar
mierla

Community Member, 16 Posts

23 June 2011 at 2:06pm

I've got a fairly complex set of data (at least for me) and I can't figure out how to get point A to point D. I want to get from:
PageObject has_one DataObjectA has_many DataObjectsB has_one DataObjectC. I want fields form DataObjectC to be available on my PageObject, and I can't figure out how to get anything other than the ID.
Here are the Page and DataObjects, all managed through Uncle Cheese's very excellent remodelled ModelAdmin (and here with irrelevant fields removed for brevity):

class LegislativeSession extends DataObject {
   static $many_many = array( 'Legislators' => 'Legislator');
   static $has_many = array('Bills' => 'Bill');
   static $has_one = array('
}

class Legislator extends DataObject {
   static $db = array('Name'=>'Text');

   static $has_many = array(
       'Bills'=>'Bill',
       'Votes'=>'Vote');

   static $belongs_many_many = array('LegislativeSessions'=>'LegislativeSession');
}

class Bill extends DataObject {
   static $has_one = array(
       'Legislator'=>'Legislator',
       'LegislativeSession' => 'LegislativeSession');

   static $has_many = array('Votes'=>'Vote');
   
   public function getMyVotes(){
		return $this->Votes();
   }
}

class Vote extends DataObject {
   static $has_one = array(
       'Bill'=>'Bill',
       'Legislator'=>'Legislator');
}

class Scorecard extends Page {
	static $has_one = array('LegislativeSession'=>'LegislativeSession');
	
	public function getBills(){
		$legissessionid=$this->LegislativeSessionID;
		$Bills = Dataobject::get("Bill", "Bill.LegislativeSessionID = $legissessionid", "Bill.Title ASC", "LEFT JOIN LegislativeSession ON LegislativeSession.ID = Bill.LegislativeSessionID", "");
		return $Bills;
	}
	
class Scorecard_Controller extends Page_Controller {
        
  static $allowed_actions = array( 
   'retrieve_bill',
   );

   public function getIndividualBill(){ 
      if ($this->request->latestParam('Action')) { 
         $parameter = $this->request->latestParam('ID'); 
         if ($parameter) { 
            $BillID = Convert::raw2xml($parameter); 
            if($BillID){ 
               $BillInfo = DataObject::get_by_id('Bill', $BillID); 
               return $BillInfo; 
            } 
         } 
      } 
   }   
}

..and then this template:

<section class="primary">
    <% if IndividualBill %>
        <% control IndividualBill %>
        <h2>$Title</h2>
        <p>$Summary</p>
        <dl>
        <% control MyVotes %>               
            <dt>$LegislatorID</dt>
            <dd>$PositiveVote</dd>
            <% end_control %>
        </dl>
    <% else %>
		.
		.
		.
    <% end_if %>
</section>
<section class="secondary">
    <% control getBills %>
    <ul>
        <li><a href="{$Top.Link}retrieve_bill/$ID" class="$LinkingMode">$Title</a></li>
    </ul>
    <% end_control %>
</section>

I want to list Legislator Name on the Scorecard Page, and I tried adding this to the Bill object:
public function Voter() {
        $this->getComponent('Legislator');
		}

and calling

<% control Voter %>
$Voter.Name
<% end_control %>

..but that doesn't return anything. Help, please?

Avatar
zenmonkey

Community Member, 545 Posts

28 June 2011 at 9:08am

Silverstripe should take care of your relationships for you. You just need to call the <% control Legislator %> instead of $LegislatorID, that way you'll have full access to the entire dataobject.

The other option is use a function like this on Vote

function getLegislatorName() {
return "Legislator.Name";
}

That way $LegislatorName becomes a property on the Vote object

Look into the dot notation stuff and get property calls, you can do a lot of cool stuff. I just figured it out a few months ago and love it