2011-02-22 79 views
10

机场有四个字母的ICAO代码。按照惯例,这些总是大写的。我正在创建一个用于接收用户输入的表单,但是此表单需要能够接受混合大小写的用户输入,并防止他们创建模糊。Rails - 强制字段大写并且唯一验证

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

例如,如果已经有一个国际民航组织的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 

回答

2

简单地固定(如许多问题轨) - 丹尼上面所指出的,虽然不是在他自己的答案,所以我不能接受它:),将before_save更改为before_validation可以很好地修复它。

7

试试这个:

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

或做before_validation代替before_save :) – 2011-02-22 19:54:07

+1

完美,丹尼的更新答案 - before_validation是正是我需要的。 – tkrajcar 2011-02-22 20:06:31

9

还是略有不同的看法:写出icao一个setter是什么转换扔给它为大写:

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

然后你就可以使用普通的独特性验证(back it up with a unique index in your DB)。在查找过程中,甚至可能让数据库变得更容易一些,因为它不必担心不区分大小写的比较。

希望这会有所帮助!

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