Какой лучший способ сделать регистр без учета регистра в Rails?

Я работаю над проектом RoR, где у меня есть модель со строковым атрибутом, которая должна быть полностью без учета регистра. Мне просто интересно, что лучший способ сделать это.

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

Есть ли способ сделать это на уровне БД? Я использую Postgres. Если нет, то как лучше всего подойти к этой проблеме? Получает ли база данных большой успех при поиске без учета регистра? Что с точки зрения безопасности? Разве безопаснее проверять регистр без учета регистра каждый раз, чтобы предотвратить проблемы, если кто-то каким-то образом создаст строчную строку? В основном, что является лучшей практикой в ​​этом?

1 ответ

Решение

Столбец БД никогда не учитывает регистр. Ваше взаимодействие может быть без учета регистра. Как вы видели, есть несколько возможных случаев и решений.

Если атрибут имеет смысл только в случае, но вы хотите разрешить поиск независимо от случая, то всегда записывайте его в случай при записи в базу данных и фильтруйте запросы, которые к нему обращаются. Типичным примером является адрес электронной почты. Вы хотите хранить его всегда в нижнем регистре и обязательно запрашивать его таким образом, уменьшая регистр пользовательских вводов.

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

  1. Добавьте отдельное поле, содержащее атрибут, всегда чувствительный к регистру, и действуйте, как в предыдущем примере.
  2. Используйте функции ядра базы данных при запросе базы данных для преобразования значения во время выполнения. Имейте в виду, что это, вероятно, не позволит базе данных использовать индексы, что может привести к снижению производительности.

Есть несколько вариантов, которые вы можете сделать:

Вы можете установить локальную базу данных без учета регистра. Для примера посмотрите pg в Ubunto. Это очень сложно и зависит от ОС. Например, Mac и RHEL pg всегда чувствительны к регистру, тогда как Ubuntu pg по умолчанию нечувствителен к регистру. Хотя это было многообещающе, я не добился большого успеха. Установленные локали зависят от ОС, и мне не удалось легко отследить нечувствительный к регистру локальный вариант и информацию о его создании. Установить и распространить локальную версию было непросто. Mysql и SqlServer поставляются с собственными языковыми стандартами, в то время как pg использует языковые стандарты, предоставленные ОС. Использование собственных языковых стандартов менее гибко и потенциально преподносит сюрпризы для некоторых языков, но оно более согласованно для разных операционных систем, поскольку языковой стандарт не привязан к операционной системе.

Вы также можете установить citextрасширение. Создайте поля, которыеcitext вместо того varchar. Почти наверняка расширения попадают вschema.rb Настоящее время.Model.where(:field => "AnY cAsE").

С помощью ILIKE также будет выполнять поиск без учета регистра, даже если у вас нет подстановочного знака (%).Model.where(Model.arel_table[:field].match("AnY cAsE"))

Создать индекс на lower(field) и используйте это для поиска в таблице. LIKE против ILIKE имеют очень разные рабочие характеристики и LIKE имеет тенденцию быть намного лучше.Model.where(Model.arel_table[:field].lower.match("AnY cAsE".downcase, nil, true))

Как упоминалось выше, сохраняйте все значения в нижнем регистре. Примечание. Это можно сделать в отдельном поле, которое заполняется вbefore_validation перезвонить.Model.where(:field_lower => "AnY cAsE".downcase)

Удачи. Вы, вероятно, уже решили эту проблему, но подумали, что я поделюсь тем, что мы думали в моей компании, для вас и других.

Другие вопросы по тегам