首先,请原谅我在第三方ORM中的清洁度和缺乏经验(已经太长了"量身定制"要求)
我很难理解SilverStripe ORM
中的关系我想要实现的是将一组属性关联到单个RoomTypeId
/mymodule/models/Rooms.php
class Rooms extends DataObject
{
private static $db = array(
"RoomTypeId" => 'Int', // This needs to correlate with Attributes.RoomTypeId
"RoomTypeGroupId" => 'Int',
"SubPropertyId" => 'Int',
"Name" => 'Varchar(255)',
"Description" => 'Text',
"MaxOccupancy" => 'Int',
"Raw" => 'Int',
"NoDiscountAllowed" => 'Int',
"DefaultArrival" => 'Varchar(10)',
"DefaultDeparture" => 'Varchar(10)',
"Image1" => 'Varchar(255)',
"Image2" => 'Varchar(255)',
"Image3" => 'Varchar(255)',
"Image4" => 'Varchar(255)',
"Image5" => 'Varchar(255)',
"MinCost" => 'Currency'
);
public static $has_many = array(
"Attributes" => "Attribute"
);
}
/mymodule/models/Attributes.php
class Attributes extends DataObject {
private static $db = array(
"RoomTypeId" => 'Int', // needs to correlate with Room.RoomTypeId
"AttributeId" => 'Int',
"Name" => 'Varchar(255)'
);
private static $has_one = array(
"Rooms" => "Rooms"
);
}
然而,文档说一个列已添加到数据库<relation-name>ID
,这不符合我需要将多个属性关联到Rooms.RoomTypeId
由于我的误解和时间限制,我确实
Rooms::get()->filter([...])
Attributes::get()->filter([...])
在PHP方面,这一切都很好,但从模板的上下文中看似不合理。
任何指导都非常感谢!
注意:从外部API检索RoomTypeId
答案 0 :(得分:2)
我相信你的混淆可能源于将对象视为完整的SQL表 - 事实并非如此。 ORM允许开发人员以OOP术语工作,而不必特别担心信息的存储方式。
我希望我没有错(你的描述相当简短),但似乎你基本上只是做了太多而不是特别错误。
SilverStripe中的每个关系通常都需要设置反向。 has_one
或many_many
并非严格要求,而是has_many
。这与SilverStripe检查模型信息并为您生成存储的方式有关(参见dev/build
)。
正如你在SQL中特别熟悉的那样,我会直接跳到技术解释:
$db
用于Object的本机属性,不用于关系
数据。has_one
将在对象的表格中存储外部ID
表格<relationship name>ID
,即"Attributes"."RoomsID"
。这是为您生成的。has_many
会将对象自己的ID存储在关系表中。这不是为您生成的,因此在相关类上需要has_one
(就像在代码演示中一样)。many_many
将关系存储在自己的表中,匹配两个外部ID。一个相当传统的连接表。由于连接表的性质,并不严格要求反向,但最好以belongs_many_many
的形式设置反向。当您直接与孩子打交道时,这将让ORM知道这种关系存在。对象。您可以在http://www.silverstrip.es/blog/diagram-of-relationships-in-silverstripe/
的图片中看到上述要点作为旁注,您似乎将图像引用存储为Varchars。只有在外部保存信息时才需要这样做。如果图像是通过SilverStripe管理的,many_many
到Image
就足够了。否则,在官方SilverStripe文档网站上的第七课中有许多与对象相关的图像的例子。
此外,手动提取和过滤器可以从模板中找到。在模型(或控制器)上定义函数Rooms :: getAttributes()和/或Attributes :: getRooms()并返回get() - &gt; filter()序列将允许在模板中访问生成的查询通过会议室$Attributes
和属性$Rooms
分别。你应该小心这一点,因为它可以很容易地解决魔法提取问题(通过php&#39; s __call
)。