Не зависящее от регистра уникальное ограничение в Grails - PullRequest
5 голосов
/ 29 марта 2010

Как я могу в основном выполнить уникальное ограничение для поля типа данных строки.

class User{
  String username
  String Email

  static hasMany = [roles:Roles]

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

    }
}

Есть ли простой способ реализовать username(unique: true)

Или я должен вручную проверить базу данных, используя такие методы, как .findByNameLike?

Имя пользователя должно быть уникальным, но уникальность должна быть без учета регистра.

Ответы [ 3 ]

13 голосов
/ 29 марта 2010

Итак, если вы хотите использовать уникальные имена пользователей без учета регистра, есть два возможных подхода.

Простой:

  • Храните их в верхнем или нижнем регистре и используйте уникальное ограничение.

или, что касается производительности, дороже:

  • Храните их в смешанном регистре и используйте пользовательский валидатор , который проверяет базу данных путем сравнения заданных и существующих имен пользователей без учета регистра.

Теперь все зависит от того, хотите ли вы предоставить пользователю свободу ввода его имени пользователя в том случае, если он этого хочет (первая возможность), или вы хотите сохранить регистр имен пользователей для отображения причин (вторая возможность).

Ваш вопрос звучит как второй, поэтому пользовательский валидатор будет выглядеть так:

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 голосов
/ 11 апреля 2013

Чтобы добавить еще одно решение "быстрого и грязного" решения @air_blob, вы пробовали это?

username(validator: { val, obj ->
                      return !User.findByUsernameIlikeAndIdNotEqual(val, obj.id)                      
                    })
1 голос
/ 29 марта 2010

username(unique:true) является допустимым ограничением.

Чтобы сделать регистр нечувствительным, вам нужно написать собственный валидатор. См. эту ветку обсуждения для дополнительной информации.

...