SilverStripe GridField:创建了太多版本的DataObject

时间:2013-03-26 17:05:49

标签: silverstripe

TL; DR 在创建/保存与某个页面相关的版本化DataObject时,会在相应的版本表中创建两个条目(而不是一个)。

我正在尝试对某些DataObject进行版本化,并按如下方式应用Versioned扩展名:

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

Testobjects在某个页面上的GridField中进行管理,如下所示:

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);
    }

现在,只要我在GridField的EditForm中添加或保存一些Testobject,就会在Testobject_versions表中显示两个新条目。对于比较,当我在SiteTree中保存页面时,只会在相应的版本表中创建一个条目。

由于页面上会有数千个这样的DataObjects,我担心这个重复会填满我的数据库。有办法解决这个问题吗?

进一步表彰:

  • 在创建新的Testobject时,versions表中的第一个条目将其PageID字段设置为0,第二个条目设置了相应页面的实际PageID。

  • 如果我按$this->Testobjects()替换GridField构造中的Testobject::get(),则只会在版本表中显示一个条目。

  • 使用$this->Testobjects()时调用onBeforeWrite两次

所以看起来设置与页面的关系发生在第一个'write()'之后,然后调用另一个'write()'。但是在代码中这发生了什么?

1 个答案:

答案 0 :(得分:0)

如果你在CMS的主要部分(@'/ admin / pages')编辑你的页面/测试对象,你可以尝试在你的TestObject类中使用这个有点hackish的技巧

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

由于以下原因,这并不理想:

  • 难以使用单元测试控制器进行测试
  • 模型中控制器的意识不好 IMHO

但如果它对你有用,它可能是一个合理的解决方法