Rails“validates_uniqueness_of”区分大小写

时间:2009-03-27 17:14:47

标签: ruby-on-rails validation model

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

class School < ActiveRecord::Base

  validates_uniqueness_of :name

end

例如,在我添加“耶鲁”之后,我无法添加“耶鲁”,但可以添加“耶鲁”。如何使验证不敏感?

编辑:找到它 - Active Record Validations

4 个答案:

答案 0 :(得分:221)

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

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

    来自Ruby on Rails 3rd Edition

      

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

    另见this programmer's experience validates_uniqueness_of

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

答案 1 :(得分:70)

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

validates :name, :uniqueness => true

或没有case_sensitivity

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

答案 2 :(得分:21)

您可以选择指定不区分大小写

  validates_uniqueness_of :name, :case_sensitive => false

答案 3 :(得分:1)

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

基本上,使用:case_sensitive => false执行效率非常低的数据库查询。