使用silverstripe ORM进行混乱

时间:2016-09-02 04:42:14

标签: orm silverstripe

首先,请原谅我在第三方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

1 个答案:

答案 0 :(得分:2)

我相信你的混淆可能源于将对象视为完整的SQL表 - 事实并非如此。 ORM允许开发人员以OOP术语工作,而不必特别担心信息的存储方式。

我希望我没有错(你的描述相当简短),但似乎你基本上只是做了太多而不是特别错误。

SilverStripe中的每个关系通常都需要设置反向。 has_onemany_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_manyImage就足够了。否则,在官方SilverStripe文档网站上的第七课中有许多与对象相关的图像的例子。

此外,手动提取和过滤器可以从模板中找到。在模型(或控制器)上定义函数Rooms :: getAttributes()和/或Attributes :: getRooms()并返回get() - &gt; filter()序列将允许在模板中访问生成的查询通过会议室$Attributes和属性$Rooms分别。你应该小心这一点,因为它可以很容易地解决魔法提取问题(通过php&#39; s __call)。