2010-03-29 34 views
4

我如何基本上對字符串數據類型字段執行唯一約束。Grails中不區分大小寫的唯一約束

class User{ 
    String username 
    String Email 

    static hasMany = [roles:Roles] 

    static constraints = { 
    Email(email:true) 
    username(unique:true) 

    } 
} 

是否有實現username(unique: true)

什麼簡單的辦法還是必須手動檢查使用像.findByNameLike方法的數據庫?

用戶名應該是唯一的,但唯一性應該是不區分大小寫的。

回答

13

所以,如果你想擁有獨特的和不區分大小寫的用戶名,有兩種可能的方法。

簡單的一個:

  • 存儲它們大寫或小寫,並使用唯一約束。

,或者關於性能,更昂貴:

  • 商店他們在大小寫混合使用custom validator,檢查通過比較給定的和現有的用戶名不區分大小寫的數據庫。

現在要看,如果你只是想給用戶的自由,他希望(第一種可能性)的情況下進入自己的用戶名或你想保留的用戶名的情況下顯示的原因(第二種可能性)。

你的問題聽起來就像是第二個,所以自定義驗證程序是這樣的:

class User { 
    String username 
    String email 

    static hasMany = [roles:Roles] 
    static constraints = { 
    email(email:true) 
    username(validator: { 
       return !User.findByUsernameILike(it) 
      }) 
    } 
} 

希望有所幫助。當用戶

[編輯]

正如他在評論海因裏希狀態,驗證上面會造成問題能夠改變他們的用戶名。

快速&髒,但我認爲這解決了這個問題:

username(validator: { val, obj -> 
         def similarUser = User.findByUsernameILike(val) 
         return !similarUser || obj.id == similarUser.id 
        }) 

當心,這不是測試,我不知道如果你能在驗證定義變量。

元:我不會讓用戶更改了自己的用戶名;)

+2

好答案!我認爲你自定義的驗證器在更新「用戶名」時可能會有問題。請參閱http://n4.nabble.com/Case-Insensitive-Constraint-td1359204.html。不知道雖然... – 2010-03-29 13:14:54

+0

Omg! 是@海因裏希你是對的,當我嘗試更新相同的字段時,它確實失敗。 – WaZ 2010-03-29 13:41:37

+0

用戶名(驗證:{VAL,OBJ - > DEF similarUser = User.findByUsernameILike(VAL) 返回similarUser ||(obj.id == similarUser.id) !}) 請告訴我obj.id的目的&&在條件。我刪除它,它仍然正常工作。 – WaZ 2010-03-29 14:06:49

1

username(unique:true)是有效的約束。

要使約束不區分大小寫,您需要編寫自定義驗證器。有關更多信息,請參閱this discussion thread

+0

配合,當我執行它時,我得到以下錯誤: 沒有這樣的屬性: id爲類:com.myCompany.User – WaZ 2010-03-29 13:46:03

+0

鏈接返回404 :( – Rafael 2015-01-14 13:12:07

+0

@Rafael我更新了鏈接,但我不確定這些信息是否仍適用 – 2015-01-14 13:18:43

2

爲了添加@air_blob的「快速和骯髒」解決方案的另一個解決方案,你嘗試過嗎?

username(validator: { val, obj -> 
         return !User.findByUsernameIlikeAndIdNotEqual(val, obj.id)      
        })