【发布时间】:2014-07-31 00:53:27
【问题描述】:
我使用 KnexJS 已经有一段时间了,并且想过渡到 BookshelfJS,因为我在服务器端的模型类开始变得有点毛茸茸,为什么要重新发明轮子。
对于我的很多 API 服务器,我想做的是预先获取相关模型的列表(一个文档有很多并且属于许多编辑器),而不必预先获取整个内容。理想情况下,我最终会得到
document = {
id: 1
body: 'foobar'
editor_ids: [1, 2]
}
现在,我可以通过在 Document 定义上执行 editors: belongsToMany(Profiles) 来做到这一点,然后执行 fetch().withRelated(['editors']),但问题是它返回了完整的 Profile获取对象。
这会生成一个不需要的无关连接 (documents_editors join editors on editors.id = documents_editors.editor_id),并符合我的客户端应用程序期望的规范(嵌入的 ID 以及稍后在 JSON 响应中添加的配置文件本身只是可选的,实际上在实践中从来没有,因为配置文件往往会被缓存并加载到其他地方),我必须通过解析 Document.relations 手动将 editor_ids 属性推入其中,这也增加了(一点点)额外时间。
所以,最终,我可以做我想做的事,但这并不优雅。理想情况下,BookshelfJS 中有一些东西我可以做类似的事情
Document = bookshelf.Model.extend
tableName: 'documents'
fancyValue: ->
@rawQuery 'select editor_id from documents_editors where document_id = ?', [@id]
或者在其中构建一个 knex 样式的查询。我知道在上述特定用例中,原始查询有点矫枉过正,但实际上我还有一些更烦人的查询要运行。我跟踪用户社区成员资格,以及对社区文档的权限授予,这意味着我使用 postgres 风格的 CTE 来做类似的事情
with usergroups as
(
select communities.id from communities inner join edges
on communities.id = edges.parent_id and edges.parent_type = 'communities'
and edges.child_id = ? and edges.child_type = 'profiles'
and edges.type = 'grant: comment'
)
select distinct documents.id as parent_id, 'documents' as parent_type
from documents inner join edges
on edges.parent_id = documents.id and edges.parent_type = 'documents'
and edges.type = 'grant: edit'
and documents.type = 'collection'
where (edges.child_type = 'profiles' and edges.child_id = ?) or
(edges.child_type = 'communities' and edges.child_id in (select id from usergroups))
(查找相关用户可以编辑的所有类型为“集合”的文档,因为它们被直接添加为编辑器,或者因为它们属于被授予编辑权限的社区)。
【问题讨论】:
标签: bookshelf.js