列を削除する移行があります:
def change
remove_column :foos, :bar, :boolean
end
rake db:rollback
その移行、次のエラーが表示されます。
remove_column is only reversible if given a type.
ActiveRecord :: Migration ドキュメントには、以下がremove_column
:
remove_column(table_name, column_name, type, options)
したがって、この場合の私の型は:boolean
、そして移行は可逆的であると期待しています。私は何が欠けていますか?
確かにこれをup
とdown
の移行に分けてこの問題を回避できますが、この場合change
構文が機能しない理由を理解したいと思います。 。
3番目の引数(列の:type)をremove_column
メソッドに追加するだけで、その移行を元に戻すことができます。そのため、次のように、OPの元のコードは実際に機能しました。
remove_column :foos, :bar, :boolean
この回答の残りの部分は、この方法が機能しなかった理由を発見する試みでしたが、OPは最終的に機能するようになりました。
ActiveRecord :: Migration :のドキュメントに多少矛盾した情報があります。
remove_columnなどの一部のコマンドは元に戻せません。これらの場合に上下に移動する方法を定義したい場合は、前と同じように上下のメソッドを定義する必要があります。
可逆的なコマンドのリストについては、ActiveRecord :: Migration :: CommandRecorderをご覧ください。
そして、これは ActiveRecord :: Migration :: CommandRecorder :
ActiveRecord :: Migration :: CommandRecorderは、移行中に実行されたコマンドを記録し、それらのコマンドを逆にする方法を知っています。 CommandRecorderは、次のコマンドを反転する方法を知っています。
add_column
add_index
add_timestamps
create_table
create_join_table
remove_timestamps
rename_column
rename_index
rename_table
とにかく、このドキュメントは古くなっているようです... githubのソース :
あなたに悲しみを与えている方法は次のとおりです。
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
私はこれを試してみました... Rails 4.1.2アプリで移行をセットアップし、移行は上下に機能しました。ここに私の移行がありました。
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
また、:boolean
引数が欠落している状態で試してみましたが、あなたが話しているのと同じエラーが発生しました。 Rails 4.1.2の最終バージョンではありますか?リリース候補の1つではありませんか?ある場合は、binding.pry
を置くことをお勧めしますRails invert_remove_column
メソッドのソースを使用して、引数リストを検査し、何が起こっているのかを確認します。これを行うには、bundle open activerecord
を実行し、次の場所に移動します:lib/active_record/migration/command_recorder.rb:128。
change
を使用する代わりに、up
およびdown
メソッドを使用して移行します。
def up
remove_column :foos, :bar
end
def down
add_column :foos, :bar, :boolean
end