我有一个DataObject“Rectangle”。它与“AttributeValue”(例如10英寸)存在许多关系。 DataObject“AttributeValue”也与“属性”(例如长度(或宽度))有许多关系。我想在CMS的“矩形”页面上创建一个表,它显示了AttributeValue和相关的属性:
属性|值
长度| 10英寸
宽度| 20英寸
颜色|红色
原因属性与Rectangle无关,我不知道如何获取该表中的数据。使用以下代码生成表的值:
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
相关的一些Attribute
(例如10英寸,20英寸,红色),所以在数据库中有一个表Rectangle_AttributeValue,它显示了这种关系。我还有与AttributeValue
(表AttributeValue_Attribute)相关的对象{{1}},例如10英寸 - >长度,或红色 - >颜色。所以整个“关系链”看起来像:Rectangle-> AttributeValue-> Attribute(Rectangle1 - > 10 inch - > length,或Rectangle1 - >>> color)。我希望我能说得更清楚......
答案 0 :(得分:0)
首先,为了清楚起见,您应该将您的many_many声明复数化,如:
private static $many_many = array('AttributeTypes' => 'AttributeType');
和
private static $belongs_many_many = array('Rectangles' => 'Rectangle');
回答你的问题“因为AttributeType与Rectangle无关,我不知道如何获取该表中的数据”:你没有,你不应该这样做。要在矩形页面中“获取”某些类型的属性,首先要创建一个具有关联类型的属性,然后将其添加到“矩形”页面。然后,您可以访问类型:
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。
请注意,如果每个矩形有很多属性,并且每个属性有很多类型,这很快就会变得混乱。
希望这会有所帮助。如果没有,请稍微澄清一下你的问题:-)
答案 1 :(得分:-1)
就个人而言,我不建议您采用的方法,因为您将获得将使用的每个唯一值的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