Search code examples
ruby-on-railsrails-migrationsruby-on-rails-5.1

Tried to change the type of a column, but Rails tries to drop the table instead


I'm trying to change the data type of a column of a table. I tried two different approaches:

def change
    remove_column :users, :permission_level
    add_column :users, :permission_level, :integer
end

And

def change
    change_column :users, :permission_level, :integer
end

However, in both cases I got this error:

SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"
/home/prios/blog/db/migrate/20170719071633_change_column_permission_level_from_string_to_integer.rb:3:in `change'
ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "users"
/home/prios/blog/db/migrate/20170719071633_change_column_permission_level_from_string_to_integer.rb:3:in `change'
SQLite3::ConstraintException: FOREIGN KEY constraint failed
/home/prios/blog/db/migrate/20170719071633_change_column_permission_level_from_string_to_integer.rb:3:in `change'
Tasks: TOP => db:migrate

It seems that Rails is trying to drop the table instead of removing/changing the data type of one of its columns, something I don't want.

Further info: The column I'm trying to alter/delete doesn't have any foreign keys associated to it. It's a column I haven't used yet.


Solution

  • SQLite doesn't support the remove_column migration method. From http://www.sqlitetutorial.net/sqlite-alter-table/:

    SQLite does not support ALTER TABLE DROP COLUMN statement.

    Apparently it's a pretty convoluted process in SQLite where you rename the existing table, create a new table without the column you want removed, copy over all the date from the original table, and then drop the original table. I ran into this when I was first getting started, made the switch to Postgres and haven't looked back.