When adding a many_many relationship much like the projects to mentors relationship in the silverstripe guide:
http://doc.silverstripe.org/framework/en/tutorials/5-dataobject-relationship-management
I'd like to record an attribute against the relationship. So for example "active" - yes /no field for the mentor on the project. But the mentor might have a different value for active for different projects she is related to.
Whats the best way to achieve this with Silverstripe's built in tools?
UPDATE with some help from IRC & the answer below. ive gotten a bit closer, bit its not working. Ive found this: https://github.com/chillu/silverstripe-framework/blob/c8136f5d4c8a37a4da274cd1c93907c0a2af86a7/docs/en/reference/grid-field.md which seems very relevant.
so DebatePages have many_many panelists who can vote differently on each debate.
DebatePage.php
  private static $many_many = array(
    'Panelists'     => 'Panelist',
    'RelationTags'  => 'Tag'
  );
  public static $many_many_extraFields = array(
    'Panelists' => array('Motion' => 'Boolean')
  );
public function getCMSFields() {
    .....
    if($this->ID) {
            $panelistFields = singleton('Panelist')->getCMSFields();
            $panelistFields->addFieldToTab(
                'Root.Main',
                // Please follow the "ManyMany[<extradata-name>]" convention
                new TextField('ManyMany[Motion]', 'Agree with Motion')
            );
            $config = GridFieldConfig_RelationEditor::create();
            $config->getComponentByType('GridFieldDetailForm')->setFields($panelistFields);
            $gridField = new GridField('Panelists', 'Panelists', $this->Panelists(), $config);
            $fields->findOrMakeTab('Root.Panelists')->replaceField('Panelist', $gridField);
        }        
    }
you could use $many_many_extraFields on the $many_many relation, like this (here on the Project class I guess):
static $many_many = array(
    'Mentors' => 'Mentor'
);
static $many_many_extraFields = array(
    'Mentors' => array(
        'Active' => 'Boolean'
    )
);
Then for each Project a specific Mentor can be active or not (you can always add other fields than 'Active'...).
If you are using SS 3.1 you can have those extra fields edited easily via a GridField with the GridFieldDetailForm component:
function getCMSFields(){
    --[snip]--
    $detailFormFields = new FieldList();
    $detailFormFields->push( new CheckBoxField(
        'ManyMany[Active]',
        'Is Mentor active?'
    ));
    $detailFormFields->push( new TextField(
        'SomeOtherField',
        'Some other title'
    ));
    $config = new GridFieldConfig_RelationEditor();
    $config->getComponentByType('GridFieldDetailForm')->setFields($detailFormFields);
    $f = new GridField('Mentors', 'Mentors', $this->Mentors(), $config);
    //push() or addFieldToTab() $f to CMSFields
    --[snip]--
}
Doc on this is here: http://doc.silverstripe.com/framework/en/3.1/reference/grid-field#customizing-detail-forms
And when retrieving the data in your code, you can use the getExtraData($componentName, $itemID) method on the ManyManyList to retrieve those extra fields values:
http://api.silverstripe.org/3.1/source-class-ManyManyList.html#178-210
(See: SS3.1 - http://api.silverstripe.org/3.1/class-CheckboxSetField.html)
Try this:
private static $many_many = array(
    'Mentors' => 'Mentor'
); 
$mentors = Mentor::get();   
$mentorFields = new CheckboxSetField(    
    'Mentors',   
    'Mentor',   
    $mentors->map(),   
    $value="1"   
);  
$fields->addFieldToTab('Root.Mentors', $mentorFields);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With