Rails验证ASCII近似的唯一性

时间:2018-08-28 21:29:04

标签: ruby-on-rails friendly-id

我希望标题不太清楚。

我正在制作arails应用,但对Rails验证有疑问。在User,rb模型文件中考虑以下代码:

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

我正在使用friendly_id gem为用户生成弹头。我不会允许用户更改其名称。我现在需要的是确保名称的唯一性,如果两个人的姓名以ascii近似转换,则不会在子段上附加UUID。

当前行为是:

用户1注册一个名称,并得到如下这样的提示:

name: "Jaiel" slug: "jaiel"

用户2现在具有相同的名称,但有些不同:

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

在这里看到的问题是,我希望进行这样的唯一性验证,即用户2将被拒绝,因为两个名称都将为他们的friendly_id生成the“ jaiel”

感谢您在此问题上的帮助

谢谢

1 个答案:

答案 0 :(得分:0)

看看ActiveSupport::Inflector.transliterate

best_color_order = ['White', 'Green', 'Blue', 'Black']

df['color'] = pd.Categorical(df['color'], categories = best_color_order, ordered=True)

df.sort_values('color').drop_duplicates('name')

     name  color
0    John  White
7     Tom  Green
10  Jerry   Blue

此外,对于这种类型的验证,您可能希望进行自定义验证(除了已有的验证之外):

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

它将首先对名称进行音译,然后使用您的验证来验证已音译的名称的唯一性。看起来像是一种解决方案,绝对不如最初的解决方案那么重。