Rails - 强制字段大写并唯一验证

时间:2011-02-22 19:45:29

标签: ruby-on-rails ruby-on-rails-3 activerecord validation

机场有四个字母的ICAO代码。按照惯例,它们总是大写的。我正在创建一个用于接收用户输入的表单,但是此表单需要能够以大小写混合的形式接受用户输入,并防止它们创建欺骗。

默认情况下,默认:uniqueness区分大小写。我想出了如何在保存之前将用户的输入转换为大写,但问题是这似乎是后验证,而不是预验证。

例如,如果已经有ICAO为KLAX的机场,则用户可以输入klax,它将被验证为唯一,然后转换为大写并存储,从而产生重复。

这是我目前的模型代码。

class Airport < ActiveRecord::Base
  validates :icao, :name, :lat, :lon, :presence => true
  validates :icao, :uniqueness => true

  before_save :uppercase_icao

  def uppercase_icao
    icao.upcase!
  end
end

4 个答案:

答案 0 :(得分:10)

或者略有不同:为icao编写一个setter,将任何抛出的东西转换为大写:

def icao=(val)
    self[:icao] = val.upcase
end

然后您可以使用常规唯一性验证(back it up with a unique index in your DB)。甚至可能会在发现期间使数据库变得更容易,因为它不再需要担心不区分大小写的比较。

希望这有帮助!

答案 1 :(得分:7)

试试这个:

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

答案 2 :(得分:5)

更新了Rails 4的答案。

class Airport < ActiveRecord::Base
  validates :icao, :name, :lat, :lon, :presence => true
  validates :icao, :uniqueness => { case_sensitive: false }

  def icao=(val)
    write_attribute :icao, val.upcase
  end
end

答案 3 :(得分:2)

简单修复(与Rails一样多的问题) - 正如Danny上面指出的那样,虽然不在他自己的答案中所以我不能接受它:),将before_save更改为before_validation修复它完美。