Grails:GORM:遍历多对多关系

时间:2012-11-26 20:47:59

标签: java hibernate grails many-to-many gorm

我有2个域对象,User和SystemRights(它是多对多的,因此1个用户可以拥有许多权限,1个权限可以由许多用户拥有)。我正在寻找一种简单的方法来检查用户是否具有所需的权利。

用户域

class User {

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

    String email;   
    String passwordHash;
}

SystemRight Domain

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        

}

3 个答案:

答案 0 :(得分:2)

如果您能够/愿意稍微改变一下,我强烈建议您执行以下操作。它会让你的生活变得如此简单。

首先,从两个域中删除SystemRight和User的hasMany,然后从SystemRight中删除belongsTo用户。

接下来,创建域以表示连接表。

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
}

为了更详细地阐述为什么这种方法充满胜利,除了实际解决问题之外,take a gander at this

答案 1 :(得分:1)

我肯定会尝试在数据库中解决这个问题。

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

return relevantUserRights.size() == requiredRights.size()

答案 2 :(得分:0)

以下情况如何?

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

(未经测试:Groovy新手在这里)