web-dev-qa-db-fra.com

Comment créer une migration pour supprimer un index uniquement s'il existe, plutôt que de lever une exception dans le cas contraire?

À l'heure actuelle, la migration en cours peut échouer si la table books n'a pas created_at ou updated_at des champs:

class AddTimestampIndexes < ActiveRecord::Migration
  def up
    remove_index :books, :created_at
    remove_index :books, :updated_at

    add_index  :books, :created_at
    add_index  :books, :updated_at
  end

  def down
    remove_index :books, :created_at
    remove_index :books, :updated_at
  end
end

Est-ce que remove_index prendre des options pour continuer silencieusement s'il ne parvient pas à supprimer l'index plutôt que de déclencher une erreur?

30
h2o

Vous pouvez utiliser le index_exists? méthode dans votre migration pour tester si l'index que vous devez supprimer est réellement là.

Jetez un œil à la documentation ici: http://apidock.com/Rails/ActiveRecord/ConnectionAdapters/SchemaStatements/index_exists%3F

Je ne l'ai pas testé, mais vous devriez pouvoir utiliser quelque chose comme ceci:

class AddTimestampIndexes < ActiveRecord::Migration
  def up
    remove_index :books, :created_at if index_exists?(:books, :created_at)
    remove_index :books, :updated_at if index_exists?(:books, :updated_at)

    add_index  :books, :created_at
    add_index  :books, :updated_at
  end

  def down
    remove_index :books, :created_at
    remove_index :books, :updated_at
  end
end

Bien que, par l'apparence des choses, vous ne vouliez vraiment les créer que si elles n'existent pas? Cela pourrait être plus approprié pour votre migration:

class AddTimestampIndexes < ActiveRecord::Migration
  def up
    add_index  :books, :created_at unless index_exists?(:books, :created_at)
    add_index  :books, :updated_at unless index_exists?(:books, :updated_at)
  end

  def down
    remove_index :books, :created_at
    remove_index :books, :updated_at
  end
end
57
Jon