递归as_array与Kohana 3 ORM的一对多关系

时间:2011-07-11 13:05:53

标签: json api kohana-3 one-to-many kohana-orm

首先,我想说我知道如何为我的问题创建丑陋的解决方案。我正在寻找好的解决方案和最佳实践:)

如何从Kohana 3 ORM对象创建深层次结构数组(以后为json_encode),包括关系类型为一对多的相关对象?

问题是ORM-> as_array()方法对“has one”和“belongs to”关系递归工作但会停止并强制您在遇到时手动使用 - > find_all() “有很多”关系。

假设我正在使用Kohana 3和内置ORM创建JSON API REST服务器。 当有人查看此网址时:www.example.com/api/user?id = 5 它们将为id = 5的用户提供JSON对象。

这些是orm-models和关系:

  • 用户 属于 国家/地区
  • 用户 有许多 消息
  • 消息 属于 类别

我希望这可以工作:

echo json_encode(
ORM::factory('user', 5)
->with('country')
->with('messages')
->with('messages:category')
->find()
->as_array()
);

给我这样的输出:

{
    name: "John"
    age: 54,
    country_id: 5,
    country: {
        name: 'Sweden',
        code: 'SE'
    },
    messages: {
        {
            content: 'Lorem ipsum dolor...',
            category_id: 1,
            category: {...}
        },
        {
            content: 'Sit amet elit...',
            category_id: 2,
            category: {...}
        },
        {
            content: 'Consectetur ipsum dolor...',
            category_id: 3,
            category: {...}
        }
    }
}

但是工作正常。 这就是你所能得到的:

{
    name: "John"
    age: 54,
    country_id: 5,
    country: {
        name: 'Sweden',
        code: 'SE'
    }
}

是否有人分叉或扩展Kohana 3 ORM以支持此类功能?
有人知道任何好的Kohana 3 api模块以某种方式为你解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

据我所知,仅使用ORM无法做到这一点。出现这种情况有两个原因:

  1. 如果messagecategory有关系,则通常意味着category与该类别中的messages具有对应关系。如果你想完整地获得message“ - 即包括它的类别 - 让我们说你也想要完整地获得category” - 即包括它的消息。这显然是一个非常糟糕的主意,因为你可以很容易地将自己设计成一个无限循环。换句话说,如果有一个神奇的“递归所有关系”能力,它将如何知道何时停止递归?

  2. 当您调用find()时,ORM在幕后所做的一切就是构建一个从数据库返回一行数据的SQL查询。但是,对于返回单行的单个查询,您要做的事情太复杂了。 (有一种方法可以使用MySQL's GROUP_CONCAT function在每个字段中使用逗号分隔值将多行检索为一行,但我向您保证不值得这么做。)

  3. 由于这两个原因,ORM的with()方法仅适用于belongs_to(在您的情况下,user的{​​{1}}和country 'message)。

    执行此查询的一种方法是将其分解为三个步骤,如下所示:

    category