run rails migrations delete data column ruby-on-rails ruby-on-rails-3.1 rails-migrations

ruby on rails - migrations - ¿Cuál es la sintaxis correcta para remove_index en una migración de Rails 3.1.0?



rollback migration rails (6)

Estoy en el proceso de agregar Devise a una aplicación Rails existente, con una tabla de Usuarios ya definida. El generador de dispositivos expulsó la siguiente migración:

class AddDeviseToUsers < ActiveRecord::Migration def self.up change_table(:users) do |t| ## Database authenticatable t.string :email, :null => false, :default => "" t.string :encrypted_password, :null => false, :default => "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, :default => 0 blah blah blah.... end add_index :users, :email, :unique => true add_index :users, :reset_password_token, :unique => true end

La migración a la baja no se genera, y estoy teniendo mucho tiempo eliminando esos índices. Estoy viendo diferentes notaciones sugeridas en la documentación y diferentes sugerencias en línea, pero ninguna de ellas parece funcionar para mí. Por ejemplo...

def self.down change_table(:users) do |t| t.remove :email t.remove :encrypted_password t.remove :reset_password_token blah blah blah... end remove_index :users, :email remove_index :users, :reset_password_token end

resultados en ...

An error has occurred, this and all later migrations canceled: Index name ''index_users_on_email'' on table ''users'' does not exist

lo cual es extraño, porque si reviso la base de datos, estoy seguro que ''index_users_on_email'' está justo ahí ...

He probado otras variaciones, incluyendo

remove_index :users, :column => :email remove_index :users, ''email''

o:

change_table(:users) do |t| t.remove_index :email end

... pero no hay dados. Estoy corriendo Rails 3.1.0, Ruby 1.9.2, rastrillo 0.9.2.2, con Postgres.

El comando que me está decepcionando es:

bundle exec rake db:rollback STEP=1

después de aplicar con éxito la migración hacia arriba. ¿Algún consejo?


Aquí está mi ejecución completa de esto (en Rails 5):

Tengo team_id como un índice en proveedores de tablas. Ya no necesito esta relación. Deshacerse de eso. Hizo lo siguiente:

1) crear la migración.

$ rails generate migration RemoveTeam_idFromVendor team_id:integer

2) Ejecutando la migración, dame este error. Y eso es porque la tabla de proveedores tiene filas cuya clave externa hace referencia al valor de clave principal de la tabla de equipo

== 20170727202815 RemoveTeamIdFromVendor: migrating =========================== -- remove_column(:vendors, :team_id, :integer) rake aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "vendors"

3) Para resolver esto y poner en marcha la migración, hice lo siguiente (Nota: estoy en dev):

$ rake db:drop Dropped database ''db/development.sqlite3'' Dropped database ''db/test.sqlite3'' $ rake db:create Created database ''db/development.sqlite3'' Created database ''db/test.sqlite3'' $ rake db:migrate ~ ~ ~ == 20170727202815 RemoveTeamIdFromVendor: migrating =========================== -- remove_column(:vendors, :team_id, :integer) -> 0.0185s == 20170727202815 RemoveTeamIdFromVendor: migrated (0.0185s) ==================


Dependiendo del tipo de base de datos, no debe preocuparse por eliminar los índices en el método self.down , ya que el índice se eliminará automáticamente de la base de datos cuando suelte la columna.

También puede utilizar esta sintaxis en su método self.down :

def self.down remove_column :users, :email remove_column :users, :encrypted_password remove_column :users, :reset_password_token end


Me gustaría ampliar la respuesta de @ iWasRobbed. Si tiene un índice en una sola columna, entonces preocuparse por remove_index no tiene sentido ya que (¡solo una suposición!) La base de datos debería ser lo suficientemente inteligente como para limpiar los recursos utilizados por ese índice. Pero en caso de que tenga varias columnas, el índice de eliminación de la columna lo reducirá a las columnas aún existentes, lo cual es una cosa totalmente sensata de hacer, pero el tipo de muestra donde puede usar explícitamente remove_index .

Solo a modo de ilustración: la migración a continuación tiene la falla de que después de ser aplicada arriba y abajo dejará el índice único en el email (lo que significa que la parte down no está haciendo su trabajo correctamente)

class AddIndexes < ActiveRecord::Migration def up add_column :users, :action_name, :string add_index :users, [:email, :action_name], unique: true end def down remove_column :users, :action_name end end

Cambiando el bloque de down a

def down remove_index :users, [:email, :action_name] remove_column :users, :action_name end

solucionará esa falla y permitirá que la migración regrese correctamente el DB al estado anterior con rake db:rollback


Para alterar una tabla y / o sus índices, use #change_table dentro de #change action de una migración. Entonces podrás crear la eliminación del índice reversible de la siguiente manera:

def change change_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end

Cuando tenga que eliminar una tabla con su índice de curso con acción #drop_table puede usar el método SchemaStatements para SchemaStatements con el método #index de Table clase Table para ConnectionAdapter :

def change drop_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end

En caso de que necesite exactamente el #up/down par #up/down en una migración. Use solo un método #change_table junto con el método #remove_index de Table clase Table para ConnectionAdapter :

def up change_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end def down change_table :users do |t| t.remove_index :email, :unique => true t.remove_index :reset_password_token, :unique => true end end

Todos los métodos están disponibles en la versión Rails de 2.1.0 o en versiones anteriores.


Para el registro, la forma de eliminar un índice por nombre es

remove_index(:table_name, :name => ''index_name'')

así que en tu caso

remove_index(:users, :name => ''index_users_on_email'')


También puede eliminar el índice especificando las columnas, que desde mi punto de vista es menos propenso a errores que escribir el nombre

remove_index :actions, :column => [:user_id, :action_name]