【问题标题】:How would I save a username in a database and keep is capitalisation whilst have an un-case sensitive validation?如何在数据库中保存用户名并保持大写,同时进行不区分大小写的验证?
【发布时间】:2013-10-28 23:24:31
【问题描述】:

我正在使用 Ruby on Rails。我想将用户名存储到数据库中,当我提取它们时,我希望它们具有与输入时相同的大小写,但我想添加一些不区分大小写的验证,以确保不能使用相同的用户名,无论如何大写。

我这样说是因为并非所有数据库适配器都使用区分大小写的索引,因此我需要在将用户名保存到数据库之前将其小写。

所以模型中的验证是这样的:

uniqueness: { case_sensitive: false }

我该怎么做呢?

【问题讨论】:

    标签: ruby-on-rails postgresql sqlite


    【解决方案1】:

    我想到了几种方法。

    简单

    您可以进行区分大小写的模型级别验证,就像您正在做的那样,并且只是验证数据库中的唯一性。

    或者,如果您坚持数据库级别的验证,那么一种与数据库无关的脏方法可能是拥有另一个字段,仅用于验证。

    add_column :users, :uppercase_username, :string, unique: true
    
    class User
      def username=
        @username = value
        uppercase_username = value.upper
      end
    end 
    

    真棒

    您可以定义自己的indexing function(可能是特定于数据库的)。

    【讨论】:

    • “简单”选项有漏洞。 “丑陋”选项(在uppercase_username 上具有数据库内唯一性约束)是可移植的方法。 “真棒”是特定于数据库的,除非您从 schema.rb 切换到 structure.sql,否则会混淆 Rails,因为 schema.rb 无法存储特定于数据库的索引。
    • 我认为“丑陋”选项是“真棒”选项
    • 我想我早就放弃了“数据库可移植性”,并且很高兴地嫁给了 postgres 和 structure.sql
    【解决方案2】:

    您提到的验证 (uniqueness: { case_sensitive: false }) 在存储时不会更改用户名的大小写,而是会简单地检查是否存在相同的电子邮件。本质上,鉴于您当前的验证,您不必担心这个问题。

    【讨论】:

    • 但不是所有的数据库适配器都使用区分大小写的索引,所以我需要进行验证然后before_save { username.downcase! }
    • @Tim 您使用的是什么数据库适配器,或者您希望此应用程序可以跨多种类型的数据库工作?
    • SQLite3 用于开发和测试,PostgreSQL 用于生产。
    • 验证将按照您的意愿进行,无需任何更改,但如果您真的想在数据库级别进行验证,请查看this question 的倒数第二个答案。
    • 将唯一性约束留在数据库之外会使您面临竞争条件和其他问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2011-08-10
    • 2021-11-03
    • 1970-01-01
    • 2021-05-21
    • 2020-08-09
    相关资源
    最近更新 更多