Silverstripe的一对一关系

时间:2012-08-07 14:01:03

标签: silverstripe

我会尽可能简单地尝试,但基本上我想要实现的是这个。

有两种页面类型,一对一关系,汽车和所有者。我希望能够通过车页上的下拉菜单选择所有者。如果车主已经与另一辆车相关联,我不希望它出现在下拉列表中。

我知道我需要一个if语句,但我发现很难弄清楚应该怎么做。我按照tutorial创建了下拉列表并且效果很好。

提前致谢。

2 个答案:

答案 0 :(得分:2)

您可以修改为您提供下拉值的功能。您的DataObject::get()来电  可以有第二个参数的过滤器。只需选择CarID为0的所有所有者。

因此,从您提供的教程中,您可以使用此修改后的代码:

new DropdownField(
    'OwnerID',
    'Please choose an owner',
    Dataobject::get("Owner","CarID='0'")->map("ID", "Title", "Please Select")
);

需要注意的两件事:

  • 这假设您的DataObjects被称为CarOwner(根据需要进行更改,但将ID保留在上面写的名称的末尾)

  • 这可能不起作用,具体取决于您如何在DataObject上设置与$has_one分配的关系。如果CarID表上没有Owner字段,则此代码对您没有帮助(您可以将其设置为反之亦然)。在这种情况下,您将必须创建一个循环遍历所有汽车的函数,然后从该DataObjectSet中删除OwnerID为0的DataObject。如果这没有意义,请添加注释。

答案 1 :(得分:1)

本杰明史密斯的答案完全适用于您要求的下拉菜单,只是想指出另一种方法:不是自己处理一对一关系,而是“HasOneComplexTableField”为您处理此问题。

为您的Car类使用以下代码:

class Car extends Page {
    public static $has_one = array(
        'Owner' => 'Owner'
    );
    function getCMSFields() {
        $fields = parent::getCMSFields();
        $tablefield = new HasOneComplexTableField(
            $this,
            'Owner',
            'Owner',
            array(
                'Title' => 'Title'
            )
        );
        $tablefield->setParentClass('Car');
        $tablefield->setOneToOne();
        $tablefield->setPermissions(array());
        $fields->addFieldToTab('Root.Content.Owner', $tablefield);
        return $fields;
    }
}

注意'setOneToOne()'调用,告诉tablefield只允许您选择尚未在另一辆车上选择的Owners。

您可以在silverstripe教程中找到有关此内容的更多信息:http://doc.silverstripe.org/framework/en/tutorials/5-dataobject-relationship-management