Рельсы проверяют уникальность в приближении ASCII - PullRequest
0 голосов
/ 29 августа 2018

Надеюсь, название не слишком неясное.

Я делаю приложение для работы с arails, и у меня есть вопрос о проверке рельсов. Рассмотрим этот код в файле User, rb model:

validates :name,
          presence: true,
          length: { maximum: 50 },
          uniqueness: { case_sensitive: false }

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

Текущее поведение:

Пользователь 1 подписывается с именем и получает слаг, как это:

name: "Jaiel" slug: "jaiel"

Пользователь 2 теперь делает то же имя, но немного другое:

name: "Jàìèl" slug: "jaiel-6558c3f1-e6a1-4199-a53e-4ccc565657d4"

Проблема здесь, как вы видите, я хочу такую ​​проверку уникальности, что Пользователь 2 был бы отклонен, потому что оба имени генерировали бы слаг "jaiel" для их friendly_id

Буду признателен за помощь в этом вопросе

Спасибо

1 Ответ

0 голосов
/ 29 августа 2018

Взгляните на ActiveSupport::Inflector.transliterate:

ActiveSupport::Inflector.transliterate('Ærøskøbing')
#=> "AEroskobing"

Кроме того, с этим типом проверки вы можете использовать пользовательскую проверку (наряду с уже имеющейся):

class User
  validate :unique_slug

  private

  def unique_slug
    names = self.class.all.map(&:asci_name)

    raise ActiveRecord::RecordInvalid.new(self) if names.include?(asci_name)
  end

  def asci_name
    ActiveSupport::Inflector.transliterate(name)
  end
end

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

Другой вариант - обратный вызов. Транслитерация имени при создании:

before_validation: :transliterate_name

def transliterate_name
  self.name = ActiveSupport::Inflector.transliterate(name)
end

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

...