0

私はしばらくの間 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))

(編集者として直接追加されたか、編集アクセス権が付与されたコミュニティに属しているために、問題のユーザーが編集できる「コレクション」タイプのすべてのドキュメントを検索します)。

4

1 に答える 1