2012-07-04 72 views
0

我有一個模型,Clients和一個對應的數據庫,其中有lastnamefirstname列。最初對[lastname, firstname]的唯一性沒有限制,並且數據庫當前包含重複項。我想清理數據庫並對模型施加約束,例如:validates_uniqueness_of :lastname, scope: :firstname對填充數據庫施加約束(違反這些約束的記錄)

我想到的想法是以某種方式備份數據,對空模型數據庫施加約束,然後將數據重新提交到重複項目中,現在我可以單獨處理異常恢復。

但是,我覺得我在這裏做了些什麼。

有沒有更好的「導軌方式」來做到這一點?

回答

1

發現問題的唯一真正的純Rails方法是遍歷每個模型並確保它仍然有效。舉例來說,大致有:

Client.all.each do |client| 
    unless (client.valid?) 
    puts "Client #{client.id} invalid: #{client.errors.full_messages}" 
    end 
end 

加載all記錄可能,如果它需要太多的內存是一個壞主意。 ActiveRecord 3.0應該是更聰明的,將它加載到塊中,但目前我無法證明這種情況。

至於你與重複數據做什麼:

  • 始終備份表格使用適當的數據庫快照工具開始之前。
  • 總是在生產數據庫上運行此數據之前,先對數據副本進行測試。
  • 總是通過編寫Rails遷移以可靠和可預測的方式執行操作來記錄您的更改。部署前重複測試。

我會假設你的生產數據庫會按照原樣進行定期快照,在這種情況下,你可以從那裏獲取測試數據。如果情況並非如此,您的首要任務應該是確保它是。

+0

但我仍然想知道如何清理無效記錄。我猜,client.destroy'不會工作,因爲客戶端無效。通過添加一個額外的字段'dupe'並將唯一性驗證更改爲:'validates_uniqueness_of:lastname,scope:[:firstname,:dupe]'解決了這個問題。 'client.dupe = true; client.destroy'然後工作(自然)。 –

+1

如果您想批量迭代,請使用Client.find_each –