J'ai une migration qui supprime une colonne:
def change
remove_column :foos, :bar, :boolean
end
Quand j'essaie de rake db:rollback
cette migration, j'obtiens l'erreur suivante:
remove_column is only reversible if given a type.
La documentation ActiveRecord :: Migration indique que ce qui suit est la signature de remove_column
:
remove_column(table_name, column_name, type, options)
Donc, mon type dans ce cas devrait être :boolean
, et je m'attends à ce que la migration soit réversible. Qu'est-ce que je rate?
Je peux certainement décomposer cela en une migration up
et down
pour éviter ce problème, mais j'aimerais comprendre pourquoi la syntaxe change
ne fonctionne pas dans ce cas .
Ajouter simplement le 3ème argument (la colonne: type) au remove_column
rend cette migration réversible. Le code original de l'OP a donc fonctionné, comme dans:
remove_column :foos, :bar, :boolean
Le reste de cette réponse était une tentative de découvrir pourquoi cette méthode n'aurait pas fonctionné, mais l'OP a fini par la faire fonctionner.
Je vois des informations quelque peu contraires dans la documentation de ActiveRecord :: Migration :
Certaines commandes comme remove_column ne peuvent pas être inversées. Si vous souhaitez définir comment monter et descendre dans ces cas, vous devez définir les méthodes de montée et de descente comme précédemment.
Pour une liste des commandes réversibles, veuillez consulter ActiveRecord :: Migration :: CommandRecorder.
Et cela depuis ActiveRecord :: Migration :: CommandRecorder :
ActiveRecord :: Migration :: CommandRecorder enregistre les commandes effectuées pendant une migration et sait comment inverser ces commandes. Le CommandRecorder sait comment inverser les commandes suivantes:
add_column
add_index
add_timestamps
create_table
create_join_table
remove_timestamps
rename_column
rename_index
rename_table
Quoi qu'il en soit, il semble que cette documentation soit obsolète ... Creuser dans la source sur github :
La méthode qui vous cause du chagrin est:
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
J'ai donné un coup de feu ... configurer une migration sur mon Rails 4.1.2 application et la migration a fonctionné dans les deux sens - de haut en bas. Voici ma migration:
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
J'ai aussi essayé avec le :boolean
argument manquant et a la même erreur que celle dont vous parlez. Êtes-vous sûr que vous êtes sur la version finale de Rails 4.1.2 - pas l'un des candidats à la sortie? Si vous l'êtes, je vous suggère de mettre un binding.pry
dans le Rails source pour le invert_remove_column
méthode pour inspecter la liste des arguments et voir ce qui se passe. Pour ce faire, exécutez simplement bundle open activerecord
puis explorez pour: lib/active_record/migration/command_recorder.rb: 128.
Au lieu d'utiliser change
, vous utilisez les méthodes up
et down
pour votre migration:
def up
remove_column :foos, :bar
end
def down
add_column :foos, :bar, :boolean
end