简体   繁体   English

Grails:GORM:遍历多对多关系

[英]Grails: GORM: Traversing Many To Many Relationships

I have 2 domain objects, User and SystemRights (It's a many to many, so 1 user can have many rights and 1 right can be owned by many users). 我有2个域对象,即User和SystemRights(这是很多对很多,因此1个用户可以拥有许多权限,而1个权限可以由许多用户拥有)。 I'm looking for a simple way to check if a user has the required rights. 我正在寻找一种简单的方法来检查用户是否具有必需的权限。

User Domain 用户域

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
}

The following did not work for me: 以下对我不起作用:

In User.class 在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));

}

Current Horrible Solution 当前的可怕解决方案

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        

}

If you're able/willing to change things up a bit, I'd highly recommend doing the following. 如果您有能力/愿意进行一些改动,强烈建议您执行以下操作。 It will make you're life so much easier. 它将使您的生活变得如此轻松。

First, remove the hasMany for SystemRight and User from both Domains and remove the belongsTo User from SystemRight. 首先,从两个域中删除hasMany for SystemRight和User,并从SystemRight中删除belongsTo用户。

Next, create the Domain to represent the join table. 接下来,创建域以表示联接表。

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]
   }
}

Then, in your User class you can add this method: 然后,在您的User类中,您可以添加以下方法:

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

Then, add this to your SystemRight Domain: 然后,将其添加到您的SystemRight域:

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

For a more detailed explenation of why this approach is full of win, aside from actually solving your problem, take a gander at this . 除了实际解决您的问题外, 详细了解这种方法为什么会成功的原因,还请多多关注。

I would definitely try to solve this in the database. 我肯定会尝试在数据库中解决这个问题。

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

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

How about the following? 接下来呢?

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

(Not tested: Groovy newbie here) (未经测试:Groovy新手在这里)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM