Commit ae7bd9f7c0d78a4c039a8511d8d045eebd9706e4

Authored by Dmitriy Zaporozhets
1 parent 3bf1cff4

Migrate invalid rows with missing iids or duplicates

app/models/milestone.rb
... ... @@ -25,6 +25,7 @@ class Milestone < ActiveRecord::Base
25 25  
26 26 scope :active, -> { with_state(:active) }
27 27 scope :closed, -> { with_state(:closed) }
  28 + scope :of_projects, ->(ids) { where(project_id: ids) }
28 29  
29 30 validates :title, presence: true
30 31 validates :project, presence: true
... ...
db/migrate/20140416074002_add_index_on_iid.rb
1 1 class AddIndexOnIid < ActiveRecord::Migration
2 2 def change
  3 + RemoveDuplicateIid.clean(Issue)
  4 + RemoveDuplicateIid.clean(MergeRequest, 'target_project_id')
  5 + RemoveDuplicateIid.clean(Milestone)
  6 +
3 7 add_index :issues, [:project_id, :iid], unique: true
4 8 add_index :merge_requests, [:target_project_id, :iid], unique: true
5 9 add_index :milestones, [:project_id, :iid], unique: true
6 10 end
7 11 end
  12 +
  13 +class RemoveDuplicateIid
  14 + def self.clean(klass, project_field = 'project_id')
  15 + duplicates = klass.find_by_sql("SELECT iid, #{project_field} FROM #{klass.table_name} GROUP BY #{project_field}, iid HAVING COUNT(*) > 1")
  16 +
  17 + duplicates.each do |duplicate|
  18 + project_id = duplicate.send(project_field)
  19 + iid = duplicate.iid
  20 + items = klass.of_projects(project_id).where(iid: iid)
  21 +
  22 + if items.size > 1
  23 + puts "Remove #{klass.name} duplicates for iid: #{iid} and project_id: #{project_id}"
  24 + items.shift
  25 + items.each do |item|
  26 + item.destroy
  27 + puts '.'
  28 + end
  29 + end
  30 + end
  31 + end
  32 +end
... ...