2013-07-04 35 views
0

我一直试图让validates_uniqueness_of为我的数据库工作。我从CSV文件中提取记录,并且要确保将所有记录都记录下来,但是当我下次检查时,如果它们只是重复项,我不想再保存它们。Rails:我如何验证我的记录,使两个记录不一样?

例子中的物体

​​

示例记录

2013-01-01, 11A, Jacobsen, Mike, 11, 4, 7, 0 0 
2013-01-01, 11A, Jacobsen, Mike, 0, 0, 0, 2, 1 

我想保留这两个记录,但是当我试图验证这样的...

validates_uniqueness_of :uniform_number, :scope => [:session_date, :last_name] 

this只会保留第一个记录,并且认为第二个记录是重复记录。 我希望在第二条记录经历保存尝试时它也会保存第二条记录。

回答

1

问题是,您只验证三个字段的唯一性而不是所有字段。您应该将所有字段添加到:scope。但是如果你有一张行数太多的表格,那么这将不是很好的表现。我建议你从想要验证唯一性的所有字段中生成一个标记,并在标记上添加唯一性验证。通过这条路线,您必须在表格中添加一列以存储计算出的令牌。不要忘记在列上添加唯一索引以获得最佳性能。之后应该做的伎俩:

before_validate :generate_unique_token 

# assuming you named your slug column `unique_token` 
validates :unique_token, uniqueness: true 

private 
# add all fields you want to validate uniqueness on 
UNIQUE_FIELDS = [:uniform_number, :session_date, :more_fields] 
def generate_unique_token 
    return if self.unique_token.present? 
    token_string = '' 

    # additional comma is to ensure that [1, 10] and [11, 0] don't get treated as same input 
    UNIQUE_FIELDS.each {|field| token_string << self.send(field).to_s << ','} 

    self.unique_token = token_string 
end 

这个字符串可以变大,但你不会得到任何虚假的冲突。如果你想控制生成的令牌的大小,你可以像下面:

def generate_unique_token 
    token_string = '' 
    UNIQUE_FIELDS.each {|field| token_string << self.send(field).to_s << ','} 
    self.unique_token = compress_token(token_string) 
end 

def compress_token(token_string) 
    # you can further compress the token by encoding it in base 62/64 
    ::Digest::SHA256.hexdigest(token_string) 
end 

但要注意,后来的溶液可以具有罕见的假冲突。

+0

试过你的方法,但它似乎没有插入到数据库中,所以我试图现在调试。此外,我曾试图把所有的领域都纳入范围,但由于某些原因,以前没有工作......不知道为什么。谢谢您的帮助! – daveomcd

+0

不知道我真的改变了什么,但看起来正在使用你的方法。也非常感谢解释! – daveomcd

+1

我很高兴它为你工作:) – rubish

相关问题