私はしばらくの間 KnexJS を使用してきましたが、サーバー側のモデル クラスが少し複雑になり始めているため、BookshelfJS に移行したいと考えています。
多くの API サーバーで、関連するモデル (ドキュメントには多数のモデルがあり、多くのエディターに属しています) のリストをプリフェッチする必要がありますが、必ずしも全体をプリフェッチする必要はありません。理想的には、私は
document = {
id: 1
body: 'foobar'
editor_ids: [1, 2]
}
今、これを行うには、ドキュメント定義で 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))
(編集者として直接追加されたか、編集アクセス権が付与されたコミュニティに属しているために、問題のユーザーが編集できる「コレクション」タイプのすべてのドキュメントを検索します)。