Silverstripe 3.1表的多重many_many关系



我有一个数据对象"Rectangle"。它与"AttributeValue"(例如10英寸)处于多y_many关系中。数据对象"AttributeValue"也与"Attribute"(例如长度(或宽度))处于多y_many关系中。我想在CMS页面"矩形"上创建一个表,其中显示AttributeValue和相关属性:

属性|值

长度| 10英寸

宽度| 20英寸

color | red

原因属性是不相关的矩形,我不知道如何获得该表中的数据。表的值是用下面的代码生成的:

class Rectangle extends Page {
    private static $db = array(...);
    private static $many_many = array(
        'AttributeValue' => 'AttributeValue',
    );
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $config = GridFieldConfig_RelationEditor::create();
        $config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
            'AttributeValue'=>'Value'
        ));
        $attrField = new GridField(
            'AttributeValue',
            'AttributeValue',
            $this->AttributeValue(),
            $config
        );
        $fields->addFieldToTab('Root.Attribute', $attrField);        
        return $fields;
    }
}
class AttributeValue extends DataObject {
    private static $db = array('AttributeValue' => 'Varchar');
    private static $belongs_many_many = array('Rectangle' => 'Rectangle');
    private static $many_many   = array('Attribute' => 'Attribute');
}
class Attribute extends DataObject {
    private static $db = array('Attribute' => 'Varchar');   
    private static $belongs_many_many = array('AttributeValue' => 'AttributeValue');
}
编辑:

我有一个Rectangle与一些AttributeValues相关的(例如10英寸,20英寸,红色),所以在数据库中有一个表Rectangle_AttributeValue,它显示的关系。我还有与AttributeValue相关的对象Attribute(表AttributeValue_Attribute),例如10英寸->长度,或红色->颜色。所以整个"关系链"看起来像:矩形->AttributeValue->属性(矩形-> 10英寸->长度,或矩形->红色->颜色)。

首先,为了清晰起见,您可能应该将many_many声明复数化,例如:

private static $many_many   = array('AttributeTypes' => 'AttributeType');

private static $belongs_many_many = array('Rectangles' => 'Rectangle');

回答你的问题"原因AttributeType是不相关的矩形,我不知道如何获得数据在那个表":你不,你不应该。要在矩形页面中获得具有特定类型的属性,您应该首先创建具有相关类型的属性,然后将其添加到矩形页面。然后可以访问如下类型:

foreach($this->AttributeValues() as $attribute) {
    echo "attribute: ".$attribute->AttributeValue."<br />";
    foreach($attribute->AttributeTypes() as $type) {
        echo "type: ".$type->AttributeType."<br />;
    }
}

但是也许您只是想在CMS的后端显示类型,在矩形页面上。为此,您可以在矩形对象的静态$summary_fields中添加一个额外的、不存在的字段,例如

private static $summary_fields = array(
    "yourfield" => "CMS Titel", //one line per field you want in the summary
    "AttributeValuesAndTypes" => "Attribute values and types"
);
你可以使用上面的代码在你的矩形类中做这样的事情:
public function getAttributeValuesAndTypes() {
    $attributes = array();
    foreach($this->AttributeValues() as $attribute) {
        $types = array();
        foreach($attribute->AttributeTypes() as $type) {
            $types[] = $attribute->AttributeType;
        }
        $attributes[] = $attribute->AttributeValue." (".implode(",",$types).")";
    }
    return implode(",",$attributes);
}

这将在你的概述中添加一个额外的列,"属性1(类型1,类型2),属性2(类型2,类型3)等"。作为额外的好处,您可以摆脱额外的getCMSFields内容。

请注意,当每个矩形有很多属性,每个属性有很多类型时,这可能很快就会变得混乱。

希望这对你有帮助。如果没有,请澄清一下你的问题:-)

就我个人而言,我不建议你采取的方法,因为你将有一个Attribute记录的每一个唯一的值将被使用;因此,设置将几乎看起来像一个EAV模型。EAV模型是坏的

话虽如此,这可能是唯一的方法。我的结构是这样的:

class Rectangle extends Page {
    private static $many_many = array(
        'Attributes' => 'Attribute'
    );
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->addFieldToTab('Root.Attributes', new GridField('Attributes', 'Attributes', $this->Attributes(), GridFieldConfig_RelationEditor::create()));
        return $fields;
    }
}
class Attribute extends DataObject {
    static $db = array(
        'Title' => 'Varchar(255)', // You may want to make this an enum to limit what gets added 'Enum(array("Length", "Width", "Colour"))'
        'Value' => 'Varchar(255)'
    );
    static $belongs_many_many = array(
        'Pages' => 'Page'
    );
    static $summary_fields = array(
        'Title',
        'Value'
    );
    static $searchable_fields = array(
        'Title',
        'Value'
    );
}

这里不需要第三个模型。名称和值被存储为Attribute,并附加到页面。

我使用与此几乎相同的结构来保存我的商务模块中产品的属性。简直妙不可言

让我知道你对这个方法的看法。

更多关于EAV的信息:http://en.wikipedia.org/wiki/Entity-attribute-value_model

最新更新