diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/tasks/tags.rake | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/tasks/tags.rake b/lib/tasks/tags.rake new file mode 100644 index 00000000..7521c2f9 --- /dev/null +++ b/lib/tasks/tags.rake | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | namespace :tags do | ||
| 2 | desc "Merge tags differing only in case into one lowercase tag and " \ | ||
| 3 | "lowercase every remaining name. Idempotent; safe to re-run." | ||
| 4 | task :merge_case_duplicates => :environment do | ||
| 5 | merged = renamed = 0 | ||
| 6 | |||
| 7 | ActiveRecord::Base.transaction do | ||
| 8 | ActsAsTaggableOn::Tag.pluck(Arel.sql("DISTINCT LOWER(name)")).each do |lower| | ||
| 9 | group = ActsAsTaggableOn::Tag.where("LOWER(name) = ?", lower).order(:id).to_a | ||
| 10 | keeper = group.find { |t| t.name == lower } || group.first | ||
| 11 | |||
| 12 | (group - [keeper]).each do |dup| | ||
| 13 | dup.taggings.find_each do |tagging| | ||
| 14 | duplicate = ActsAsTaggableOn::Tagging.where( | ||
| 15 | :tag_id => keeper.id, | ||
| 16 | :taggable_type => tagging.taggable_type, | ||
| 17 | :taggable_id => tagging.taggable_id, | ||
| 18 | :context => tagging.context, | ||
| 19 | :tagger_type => tagging.tagger_type, | ||
| 20 | :tagger_id => tagging.tagger_id).exists? | ||
| 21 | duplicate ? tagging.destroy : tagging.update!(:tag_id => keeper.id) | ||
| 22 | end | ||
| 23 | dup.reload.destroy! | ||
| 24 | merged += 1 | ||
| 25 | end | ||
| 26 | |||
| 27 | if keeper.name != lower | ||
| 28 | keeper.update!(:name => lower) | ||
| 29 | renamed += 1 | ||
| 30 | end | ||
| 31 | ActsAsTaggableOn::Tag.reset_counters(keeper.id, :taggings) | ||
| 32 | end | ||
| 33 | end | ||
| 34 | |||
| 35 | puts "Merged #{merged} duplicate tags, lowercased #{renamed} names" | ||
| 36 | end | ||
| 37 | end | ||
