5

Our site has an object called "TrailNotice" which has a many_many relationship with the page type "TrailSection".

class TrailNotice extends DataObject {

  private static $many_many = array(
    'TrailSections' => 'TrailSection'
  );

This allows a single TrailNotice to be applied across multiple TrailSections via checkboxes in the CMS:

$fields->addFieldToTab('Root.Main', new CheckboxSetField('TrailSections', 'Applies to which trail sections?', DataObject::get('TrailSection')->map('ID', 'Title')));

How do I display the TrailNotices attached to a TrailSection in the TrailSection page controller?

I started with the following code:

class TrailSection_Controller extends Page_Controller {

  public function TrailNotices(){
    $TrailNotices = DataObject::get('TrailNotice');
    return $TrailNotices;
  }

But this will get all TrailNotice objects. How do I filter them so only TrailNotices attached to the TrailSection are displayed?

BaronGrivet
  • 4,364
  • 5
  • 37
  • 52

3 Answers3

7

You need to define a many_many on both ways, then you can access it from both sides. One side has a $many_many

class TrailNotice extends DataObject {

  private static $many_many = array(
    'TrailSections' => 'TrailSection'
  );

on the other side you have to define $belongs_many_many

class TrailSection extends DataObject {

  private static $belongs_many_many = array(
    'TrailNotices' => 'TrailNotice'
  );

Then in your template you can just call the relation list and loop over it:

<% loop $TrailNotices %>
    $Title
<% end_loop %>

See infographic for all possible relations (thanks to @nightjar for providing the graphics).

wmk
  • 4,598
  • 1
  • 20
  • 37
3

You have to implement a $belongs_many_many into your TrailSection model, something like that:

class TrailSection extends DataObject {

  private static $belongs_many_many = array(
    'TrailNotices' => 'TrailNotice'
  );

}

Then you can simply loop over $TrailNotices into TrailSection.ss template, without doing anything into your controller:

<% loop $TrailNotices %>
    $Title<br>
<% end_loop %>

You can check the Mentor sample in Stephen's link Dataobject Relationship Management

g4b0
  • 929
  • 1
  • 8
  • 21
0

SilverStripe stores many_many relations RelationList that can be access on the object using $this->RelationName() (in this case $this->data()->TrailNotices()). The RelationList is a subclass of DataList so you can treat it a lot like a DataObject::get() for filtering the list.

class TrailSection_Controller extends Page_Controller {

  public function TrailNotices(){
    $TrailNotices = $this->data()->TrailNotices();
    return $TrailNotices;
  }

There is more information about SilverStripe's ORM and DataObject Relations in the help section Dataobject Relationship Management and (newer content) SilverStripe Lessons

Stephen
  • 146
  • 7