Rails“validates_uniqueness_of”区分大小写

这里是模型(我正在使用SQLLite3):

class School < ActiveRecord::Base validates_uniqueness_of :name end 

例如,我添加“耶鲁”后,我不能添加“耶鲁”,但可以添加“耶鲁”。 我怎样才能使validation的情况下不敏感?

编辑:发现它 – 活动loggingvalidation

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

  1. 进程A得到一个请求来创build一个名为“foo”的新用户,
  2. 过程B做同样的事情
  3. 过程A通过询问数据库来validation“foo”的唯一性,该数据库名称是否存在,数据库表示该名称尚不存在。
  4. 进程B做同样的事情,得到相同的回应
  5. 进程A提交新logging的insert语句并成功
  6. 如果数据库约束要求该字段具有唯一性,那么进程B将为新logging提交insert语句,并且会失败 ,并返回从SQL适配器返回的丑陋服务器exception。 如果你没有数据库约束,插入将会成功,你现在有两行'foo'作为名字。

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

从Ruby on Rails第3版 :

尽pipe它的名字,validates_uniqueness_of并不能保证列值是唯一的。 它所能做的就是validation在执行validation时,没有列的值与正在validation的logging中的值相同。 可以同时创build两个logging,每个logging对于应该是唯一的列具有相同的值,并且两个logging都可以通过validation。 执行唯一性的最可靠方法是使用数据库级别的约束。“

另请参阅此程序员使用validates_uniqueness_of 的经验 。

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

在rails 3中,你可以在你的模型中做到这一点:

 validates :name, :uniqueness => true 

或者没有case_sensitivity

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

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

  validates_uniqueness_of :name, :case_sensitive => false 

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

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