0

User と SystemRights の 2 つのドメイン オブジェクトがあります (これは多対多であるため、1 人のユーザーが多数の権限を持つことができ、1 人の権限を多数のユーザーが所有できます)。ユーザーが必要な権限を持っているかどうかを確認する簡単な方法を探しています。

ユーザードメイン

class User {

    static hasMany = [systemRights: SystemRight, enterpriseUsers: EnterpriseUser]

    String email;   
    String passwordHash;
}

SystemRight ドメイン

class SystemRight {

    public static final String LOGIN = "LOGIN"
    public static final String MODIFY_ALL_ENTERPRISES = "MODIFY_ALL_ENTERPRISES"
    public static final String ADMINISTER_SYSTEM = "ADMINISTER_SYSTEM"
    public static final String VALIDATE_SUPPLIER_SCORECARDS = "VALIDATE_SUPPLIER_SCORECARDS"

    static hasMany = [users:User]
    static belongsTo = User

    String name
}

以下は私にとってはうまくいきませんでした:

User.class 内

public boolean hasRights(List<String> requiredRights) {

    def userHasRight = SystemRight.findByUserAndSystemRight (this, SystemRight.findByName(requiredRight));

    // Nor this

    def userHasRight = this.systemRights.contains(SystemRight.findByName(requiredRight));

}

現在の恐ろしい解決策

public boolean hasRights(List<String> requiredRights) {

    for (String requiredRight : requiredRights) {

        def has = false

        for (SystemRight userRight : user.systemRights) {
            if (userRight.name == requiredRight) {
                has = true
                break;
            }
        }

        if (has == false) {
            return false;
        }            
    }

    return true        

}
4

3 に答える 3

2

物事を少し変更できる/変更する意思がある場合は、次のことを強くお勧めします。それはあなたの人生をとても楽にしてくれます。

最初に、SystemRight と User の hasMany を両方のドメインから削除し、beginsTo User を SystemRight から削除します。

次に、結合テーブルを表すドメインを作成します。

class UserSystemRight {
   User user
   SystemRight systemRight

   boolean equals(other) {
      if (!(other instanceof UserSystemRight)) {
          return false
      }
      other.user?.id == user?.id && other.systemRight?.id == systemRight?.id
   }

   int hashCode() {
      def builder = new HashCodeBuilder()
      if (user) builder.append(user.id)
      if (systemRight) builder.append(systemRight.id)
      builder.toHashCode()
   }


   // add some more convenience methods here if you want like...
   static UserSystemRight get(long userId, long systemRightId, String systemRightName) {
       find 'from UserSystemRight where user.id=:userId and systemRight.id=:systemRightId and systemRight.name=:systemRightName',
            [userId: userId, systemRightId: systemRightId, systemRightName: systemRightName]
   }
}

次に、 User クラスに次のメソッドを追加できます。

Set<SystemRight> getSystemRights() {
    UserSystemRight.findAllByUser(this).collect { it.systemRight } as Set
}

次に、これを SystemRight ドメインに追加します。

Set<User> getUsers() {
    UserSystemRight.findAllBySystemRight(this).collect { it.user } as Set
}

実際に問題を解決することは別として、このアプローチが勝利に満ちている理由のより詳細な説明については、これをてください。

于 2012-11-26T21:03:33.753 に答える
1

私は間違いなくデータベースでこれを解決しようとします。

def relevantUserRights = SystemRight.withCriteria {
    eq("user", this)
    "in"("name", requiredRights);
}

return relevantUserRights.size() == requiredRights.size()
于 2012-11-27T00:07:37.193 に答える
0

以下はいかがでしょうか?

public boolean hasRights(List<String> requiredRights) {
    return null != (this.systemRights.find { requiredRights.contains(it) });
}

(未テスト: ここでは Groovy 初心者)

于 2012-11-26T21:21:29.130 に答える