2012-07-04 39 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 –