Какой лучший способ сделать регистр без учета регистра в Rails?
Я работаю над проектом RoR, где у меня есть модель со строковым атрибутом, которая должна быть полностью без учета регистра. Мне просто интересно, что лучший способ сделать это.
Я видел несколько случаев, когда люди добавляли в свои модели сеттеры, которые вводят строку в верхний регистр, прежде чем она будет помещена в базу данных, и я видел некоторых людей, которые делают свои запросы нечувствительными к регистру при поиске в базе данных.
Есть ли способ сделать это на уровне БД? Я использую Postgres. Если нет, то как лучше всего подойти к этой проблеме? Получает ли база данных большой успех при поиске без учета регистра? Что с точки зрения безопасности? Разве безопаснее проверять регистр без учета регистра каждый раз, чтобы предотвратить проблемы, если кто-то каким-то образом создаст строчную строку? В основном, что является лучшей практикой в этом?
1 ответ
Столбец БД никогда не учитывает регистр. Ваше взаимодействие может быть без учета регистра. Как вы видели, есть несколько возможных случаев и решений.
Если атрибут имеет смысл только в случае, но вы хотите разрешить поиск независимо от случая, то всегда записывайте его в случай при записи в базу данных и фильтруйте запросы, которые к нему обращаются. Типичным примером является адрес электронной почты. Вы хотите хранить его всегда в нижнем регистре и обязательно запрашивать его таким образом, уменьшая регистр пользовательских вводов.
И наоборот, если в поле, которое вы хотите сохранить, регистр важен (например, название или бренд), но вы хотите разрешить взаимодействие без учета регистра, у вас есть в основном два варианта
- Добавьте отдельное поле, содержащее атрибут, всегда чувствительный к регистру, и действуйте, как в предыдущем примере.
- Используйте функции ядра базы данных при запросе базы данных для преобразования значения во время выполнения. Имейте в виду, что это, вероятно, не позволит базе данных использовать индексы, что может привести к снижению производительности.
Есть несколько вариантов, которые вы можете сделать:
Вы можете установить локальную базу данных без учета регистра. Для примера посмотрите 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)
Удачи. Вы, вероятно, уже решили эту проблему, но подумали, что я поделюсь тем, что мы думали в моей компании, для вас и других.