1
votes

TL;DR When creating/saving a versioned DataObject with relation to some page, two entries are created in the corresponding versions table (instead of one).

I'm trying to version some DataObject and have the Versioned extension applied as follows:

class Testobject extends DataObject {
    static $has_one = array(
        'Page' => 'Page'
    );
    static $extensions = array(
        "Versioned('Stage', 'Live')",
    );

Testobjects are being managed in a GridField on some page like so:

class PageContent extends Page {
    public static $has_many = array(
        "Testobjects" => "TestObject"
    );
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $config = GridFieldConfig_RelationEditor::create();
        $gridField = new GridField(
            'Testobjects',
            'Testobject', 
            $this->Testobjects(),
            $config);
        $fields->addFieldToTab('Root.Main', $gridField);
    }

Now, whenever i add or save some Testobject in the GridField's EditForm, two new entries show up in the Testobject_versions table. For comparsion, when i save a page in the SiteTree, only one entry in the corresponding versions table is created.

As there will we thousands of these DataObjects on a page, i'm worried about this duplication filling up my database. Is there a way to get around this?

Further recognitions:

  • On creation of a new Testobject, the first entry in the versions table has it's PageID field set to 0, the second entry has set the actual PageID of the corresponding page.

  • If I replace $this->Testobjects() in the GridField construction by Testobject::get(), only one entry shows up in the versions table.

  • onBeforeWrite is called twice when using $this->Testobjects()

So it seems setting the relation to the page happens after a first 'write()', then another 'write()' is called. But where in the code does this happen?

1

1 Answers

0
votes

If you're editing your page/testobject in the main section of the CMS (@ '/admin/pages'), you can try this somewhat hackish trick in your TestObject class

public function getCMSFields(){
    $fields = parent::getCMSFields();
    $fields->push( new HiddenField('PageID','PageID', Controller::curr()->CurrentPageID());
    return $fields;
}

This is not ideal for the following reasons:

  • hard to test with unit test controller
  • awareness of the controller in the model is bad IMHO

But it can be a reasonable fix if it works for you