Error removing column Rails

2019-07-28 20:00发布

In my Rails app, I have a model called Rutinas. After some time, I needed to add some columns to the table so I generated a migration 20171116094810_add_votos_y_veces_asignada_to_rutinas.rb:

class AddVotosYVecesAsignadaToRutinas < ActiveRecord::Migration[5.1]
  def change
    add_column :rutinas, :votos_pos, :integer, :default => 0
    add_column :rutinas, :votos_neg, :integer, :default => 0
    add_column :rutinas, :veces_asig, :integer, :default => 0
  end
end

After some other migrations, I needed to delete two columns that I don't need anymore votos_pos and votos_neg so I generated another migration 20171117092026_remove_votos_from_rutinas.rb:

class RemoveVotosFromRutinas < ActiveRecord::Migration[5.1]
  def change
    remove_column :rutinas, :votos_pos, :integer
    remove_column :rutinas, :votos_neg, :integer
  end
end

The problem is that when I run rails db:migrate to migrate this last migration, it throws some weird error:

== 20171117092026 RemoveVotosFromRutinas: migrating ===========================
-- remove_column(:rutinas, :votos_pos)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "rutinas"
C:/Users/pepe/Dropbox/pepe/KeepMeFit/KeepMeFit-git/db/migrate/20171117092026_remove_votos_from_rutinas.rb:3:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'

Caused by:
ActiveRecord::InvalidForeignKey: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "rutinas"
C:/Users/pepe/Dropbox/pepe/KeepMeFit/KeepMeFit-git/db/migrate/20171117092026_remove_votos_from_rutinas.rb:3:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'

Caused by:
SQLite3::ConstraintException: FOREIGN KEY constraint failed
C:/Users/pepe/Dropbox/pepe/KeepMeFit/KeepMeFit-git/db/migrate/20171117092026_remove_votos_from_rutinas.rb:3:in `change'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

My Rutinas model is the following:

class Rutina < ActiveRecord::Base    
  validates_presence_of :nombre

  belongs_to :user
  has_many :repeticions
  has_many :entrenos, dependent: :destroy
  has_many :votos

  has_many :days, dependent: :destroy

  def get_array_dias
    (1..self.repeticions.last.dia).to_a
  end

  def get_number_of_days
    days.count
  end

end

User, repeticion, entreno, voto and day are other tables which are non-related to the columns that I'm trying to delete. That is to say, these columns are not a foreign key and any foreign key references these columns.

2条回答
三岁会撩人
2楼-- · 2019-07-28 20:02

It will be fixed in Rails 6 including https://github.com/rails/rails/pull/32865 . This requires SQLite database 3.8 and higher. I do not think it will be back ported into Rails 5.2 or older.

My answer may not give you any practical feedback how to write your code, what I can say now is upgrading Rails 6 (release date is not fixed) may resolve this problem.

查看更多
我只想做你的唯一
3楼-- · 2019-07-28 20:20

It seems like the problem is the limitation of SQLite. If you check the documentation you'll see, that it only allows adding a column, but not removing one: https://sqlite.org/lang_altertable.html

It is possible, that the migration actually drops the whole table and recreates it, when a column is removed. This would explain the DROP TABLE "rutinas" message. Of course if the while table is dropped, it would make sense that certain foreign key constraints fail.

查看更多
登录 后发表回答