2012-11-26 62 views
0

我有2個域對象,用戶和SystemRights(這是一個多對多的,所以1個用戶可以有很多權利,1個權利可以爲許多用戶所有)。我正在尋找一種簡單的方法來檢查用戶是否具有所需的權限。Grails:GORM:遍歷多對多關係

用戶域

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   

} 

回答

2

如果你能夠/願意改變了一點東西,我強烈建議執行以下操作。它會讓你的生活變得如此簡單。

首先,從兩個域中刪除hasMany for SystemRight和User,並從SystemRight中刪除belongsTo User。

接下來,創建表示連接表的域。

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

然後,在你的用戶類,你可以添加這個方法:

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

然後,將它添加到您的SystemRight域:

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

對於爲什麼這個更詳細的explenation除了真正解決你的問題,方法是充滿勝利的,take a gander at this

+0

您好格雷格,感謝您的回答。你是否建議失去多對多的關係?由於這些限制,我在User和Enterprise和UserEnterprise上做了這些工作。如果這是你的建議,那麼我想我會殺死我項目中的所有m2m關係。 – Spider

+1

它仍然是m2m,你只是自己管理連接表。 – Gregg

+0

完成!沒有更多的麻煩! – Spider

0

以下情況如何?

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

(未測試:這裏的Groovy新手)

+0

我完全喜歡null!=技巧。以前從未想過這件事! – Spider

1

我肯定會嘗試在數據庫中解決此問題。

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

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

+1謝謝。我測試了它並且它可以工作,但我決定使用@ Gregg的答案並重構我的域對象來創建一個明確的連接表。 – Spider