class RenameEntryContentHashToUniqueHash < ActiveRecord::Migration[5.2]
  def up
    rename_column :entries, :content_hash, :unique_hash
    change_column_default :entries, :unique_hash, ''

    # Calculate unique_hash for older entries
    Entry.all.order(published: :asc, created_at: :asc).each do |e|
      unique = ''
      unique += e.content if e.content.present?
      unique += e.summary if e.summary.present?
      unique += e.title
      hash = Digest::MD5.hexdigest(unique)

      # Dangerous!
      # If this entry has the same hash as an older entry (note that entries are processed in ascending order
      # by ther publish date) from the same feed, this entry is a duplicate. Delete it.
      if Entry.where('feed_id = ? AND unique_hash = ? AND id != ?', e.feed_id, hash, e.id).exists?
        e.destroy
      else
        # The entry is not a duplicate, save its unique hash in the DB
        e.update unique_hash: hash
      end
    end

    change_column_null :entries, :unique_hash, false
  end

  def down
    change_column_null :entries, :unique_hash, true
    Entry.update_all unique_hash: nil
    change_column_default :entries, :unique_hash, nil
    rename_column :entries, :unique_hash, :content_hash
  end
end

class RenameEntryContentHashToUniqueHash < ActiveRecord::Migration[5.2]
  def up
    rename_column :entries, :content_hash, :unique_hash
    change_column_default :entries, :unique_hash, ''

    # Calculate unique_hash for older entries
    Entry.all.order(published: :asc, created_at: :asc, id: :asc).each do |e|
      unique = ''
      unique += e.content if e.content.present?
      unique += e.summary if e.summary.present?
      unique += e.title
      hash = Digest::MD5.hexdigest(unique)

      # Dangerous!
      # If this entry has the same hash as an older entry (note that entries are processed in ascending order
      # by ther publish date) from the same feed, this entry is a duplicate. Delete it.
      if Entry.where('feed_id = ? AND unique_hash = ? AND id != ?', e.feed_id, hash, e.id).exists?
        e.destroy
      else
        # The entry is not a duplicate, save its unique hash in the DB
        e.update unique_hash: hash
      end
    end

    change_column_null :entries, :unique_hash, false
  end

  def down
    change_column_null :entries, :unique_hash, true
    Entry.update_all unique_hash: nil
    change_column_default :entries, :unique_hash, nil
    rename_column :entries, :unique_hash, :content_hash
  end
end

Use id to order entries in migration
Use id to order entries in migration

When deleting entries with duplicate hashes in this migration it is
important to leave the oldest entry alone and delete any newer
duplicates. The id attribute is used in the case of duplicate entries
with the same publish date and created_at date; in this case the entry
with the lowest id will be left alone and the rest will be considered
duplicates and deleted.
