3

カスタム ユーザー権限管理システムからAlanning:roles v2.0に移行しています。私は非常に基本的な構造を持っています:

  • 基本ユーザー
  • それぞれが特定の設定を持つユーザーのグループ。それらを「グループ」コレクションに保存します。
  • グループを管理するユーザーのグループ管理ステータス (各グループにはグループ管理者がいます)。

以前は、グループ メンバーと管理者の mongo_idを「グループ」ドキュメントに保存していました。このようにして、グループをリアクティブに公開できuserIdました。「メンバー」または「管理者」フィールドで、グループ ドキュメントにあるかどうかを確認する必要がありました。

Alanning:roles によって強制される適切な管理に切り替えたので、出版物で次のようなことを行います。

const userGroupsAsAdmin = Roles.getPartitionsForUser (this.userId, ['group_admin'])
const userGroupsAsMember = Roles.getPartitionsForUser (this.userId, ['member'])
const selector = {$or:[{'_id':{$in: userGroupsAsMember}},{'_id':{$in: userGroupsAsAdmin}}]}
const options = {}
const response = Groups.find(selector, options)
return response

Roles.getPartitionsForUser ()は の新しい関数名にすぎないことに注意してくださいRoles.getGroupsForUser ()

ここでの問題は、パブリケーションがroleコレクションの変更を監視していないため、ユーザーがメンバーになったときにパブリケーションが更新されないことです。私はこれがよくある問題であることを知っており、これを修正する 3 つの方法を知っていますが、どれも満足のいくものではありません。

  • 最良の候補: 非正規化と複製。グループ ドキュメントに自分のフィールドmembersとフィールドを保持します。admins私を悩ませているのは、同じものの 2 つのバージョンを保持し、矛盾が発生する可能性があることです。

  • パブリケーションに引数を追加し、この引数 (例: userGroupsAsMember) を使用してパブリケーションを再実行しますが、クライアントに依存し、不要な情報を送信させます。

  • 直接またはパッケージを使用して、低レベルの公開 API を使用します。Cursor.observe()過去にこれを直接実行しましたが、効率的にスケーリングできず、不要なサーバー負荷が発生するため、もう依存したくありません。

オプションがありませんか?そうでない場合、私のパブリケーションを反応的に保つための最良の方法は何ですか?

4

1 に答える 1

2

reywood:publish-compositeリアクティブ結合を作成するために使用します。

Meteor.publishComposite("my-groups", {
  find: function() {
      // findOne won't work, it's not a cursor
      return Meteor.users.find(
        {_id: this.userId},
        {fields: {roles: 1}}
      );
    },
  children: [{
    find: function(user) {
      // getPartitionsForUser allows the first parameter to be the actual user object.
      const userGroupsAsAdmin = Roles.getPartitionsForUser (user, ['group_admin']);
      const userGroupsAsMember = Roles.getPartitionsForUser (user, ['member']);
      const selector = {$or:[{'_id':{$in: userGroupsAsMember}},{'_id':{$in: userGroupsAsAdmin}}]};
      const options = {};
      const response = Groups.find(selector, options);
      return response;
    }
  }]
});

Roles.getPartitionsForUserカーソルを返さないため、リアクティブにすることはできません。Meteor.users.findそのため、呼び出しも公開する必要があります。

于 2016-04-26T12:09:06.290 に答える