2013-07-04 55 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

相關問題