Search code examples
phpsilverstripemodeladmin

ModelAdmin with a has_many relationship


I'm extending ModelAdmin to manage a DataObject and I have a $has_many relationship that is managed by another DataObject. I'd like to manage this object on another tab but am lost as to how I'd add it. My basic code:

ApplicationAdmin.php:

class Applications extends ModelAdmin {
    private static $menu_title = 'Applications';

    private static $url_segment = 'apps';

    private static $managed_models = array (
        'Application'
    );
}

Application.php

class Application extends DataObject {
    private static $db = array(
        'Name' => "varchar"
    );

    private static $has_many = array(
        'Documents' => 'Document',
    );

    public function getCMSFields() {
        $fields = FieldList::create(
            TextField::create('Name'),
        );

        return $fields;
    }
}

Document.php

class Document extends DataObject {
    private static $db = array(
        'Title' => "varchar",
    );

    private static $has_one = array(
        "Document" => "File",
        "Application" => "Application"
    );

    public function getCMSFields () {
        $fields = FieldList::create(
            TextField::create('Title'),
            $doc = new UploadField('Document')
        );
        $doc->getValidator()->setAllowedExtensions(array('pdf', 'docx'));

        return $fields;
    }   
}

Basically I'd like to manage the documents for this entry under Root.Documents tab.


Solution

  • You can use a GridField to handle the relation between Application and Document, and place that field on its own tab if you wish. Example:

    # Application.php
    public function getCMSFields() {
    
        $fields         = parent::getCMSFields();
        $nameField      = TextField::create('Name');
        $documentsField = GridField::create(
            'Documents',
            'Documents',
            $this->Documents(),
            GridFieldConfig_RelationEditor::create()
        );
    
        $fields->addFieldToTab(
            'Root.Main',
            $nameField
        );
    
        $fields->addFieldToTab(
            'Root.Documents',
            $documentsField
        );
    
        return $fields;
    
    }
    

    Your code contains a some typos in the Document class (the classname has .php in it, getValidator should be getValidator()), and that class also needs a $has_one = ['Application' => 'Application']; for the relation to work.