【问题标题】:Rails "validates_uniqueness_of" Case SensitivityRails \"validates_uniqueness_of\" 区分大小写
【发布时间】:2013-06-23 03:21:52
【问题描述】:

这是模型(我使用的是 SQLite3):

class School < ActiveRecord::Base

  validates_uniqueness_of :name

end

例如,我添加“耶鲁”后,我不能添加“耶鲁”,但能够添加“耶鲁”。如何使验证不区分大小写?

编辑:找到它-Active Record Validations

【问题讨论】:

    标签: ruby-on-rails validation model


    【解决方案1】:

    validates_uniqueness_of :name, :case_sensitive =&gt; false 可以解决问题,但您应该记住 validates_uniqueness_of 可以不是如果您有多个服务器/服务器进程(例如运行 Phusion Passenger、多个 Mongrel 等)或多线程服务器,则保证唯一性。那是因为您可能会得到以下事件序列(顺序很重要):

    1. 进程 A 收到创建名为“foo”的新用户的请求
    2. 进程 B 做同样的事情
    3. 进程 A 通过询问数据库该名称是否存在并且数据库说该名称尚不存在来验证“foo”的唯一性。
    4. 进程 B 执行相同的操作并获得相同的响应
    5. 进程A为新记录提交insert语句并成功
    6. 如果您的数据库约束要求该字段具有唯一性,进程 B 将为新记录提交 insert 语句并失败从 SQL 适配器返回的丑陋的服务器异常。如果您没有数据库约束,则插入将成功,并且您现在有两行以 'foo' 作为名称。

      另请参阅validates_uniqueness_of Rails 文档中的“并发性和完整性”。

      来自Ruby on Rails 3rd Edition

      ...尽管它的名字, validates_uniqueness_of 并不能真正保证列值是唯一的。它所能做的就是验证没有列与执行验证时正在验证的记录中的值相同。有可能同时创建两条记录,每条记录都有相同的值作为应该唯一的列,并且两条记录都通过验证。强制唯一性的最可靠方法是使用数据库级别的约束。”

      另请参阅 this programmer's experiencevalidates_uniqueness_of

      这种情况通常发生的一种方式是在创建新帐户时从网页意外重复提交。这是一个很难解决的问题,因为用户将得到的是第二个(丑陋的)错误,这会让他们认为他们的注册失败,而实际上它成功了。我发现防止这种情况的最好方法就是使用 javascript 来防止重复提交。

    【讨论】:

    【解决方案2】:

    在 rails 3 中,您可以在模型中执行此操作:

    validates :name, :uniqueness => true
    

    或不区分大小写

    validates :name, :uniqueness => {:case_sensitive => false}
    

    【讨论】:

    • 这正是我想要的。
    • 我做 Rails 已经 10 多年了。我不敢相信我只是在学习这个选项。在 Rails 中总有一些新东西要学……无论一个人的技能水平如何。
    【解决方案3】:

    有一个选项可以指定不区分大小写

      validates_uniqueness_of :name, :case_sensitive => false
    

    【讨论】:

      【解决方案4】:

      有一个类似的问题,但答案更有趣:https://stackoverflow.com/a/6422771

      基本上,使用:case_sensitive =&gt; false 会执行非常低效的数据库查询。

      【讨论】:

      • 这可能曾经是正确的,但现在(至少 rails 6,如果不是更早的话)它执行了一个非常有效的 EXISTS 查询。验证期间的查询将无法利用 name 上的常规索引,但为了保证并发性,无论如何,lower(name) 上应该有一个唯一索引,并且查询确实可以使用它.
      猜你喜欢
      • 2010-10-15
      • 2011-01-13
      • 1970-01-01
      • 2023-01-18
      • 2015-07-26
      • 2011-05-12
      • 2010-12-29
      • 1970-01-01
      • 2012-12-01
      相关资源
      最近更新 更多