Search code examples
mysqlruby-on-railsforeign-keysruby-on-rails-5rails-migrations

Rails migrations—temporarily ignore foreign key constraint?


I'm trying to change a table's id field to be a uuid

Here's my code:

class AddUuidToProjects < ActiveRecord::Migration[5.0]
  def up
    add_column :projects, :uuid, :string, limit:36, null: false, first: true
    add_column :projects, :old_id, :integer

    Project.all.each do |p|
      p.update!(old_id: p.id)
    end
    change_table :projects do |t|
      t.remove :id
      t.rename :uuid, :id
    end
    execute "ALTER TABLE projects ADD PRIMARY KEY (id);"

    Project.all.each do |p|
      # has_one image
      Image.find(p.old_id).update!(project: p) 
      # has_many stories
      Story.where(project_id: p.old_id).each do |s|
        s.update!(project: p)
      end
    end
  end
  ...
end

This migration breaks when trying t.remove :id, because of a foreign key constraint. The error message is:

Mysql2::Error: Cannot drop column 'id': needed in a foreign key constraint 'fk_rails_be41fd4bb7' of table 'db_dev.stories': ALTER TABLE `projects` DROP `id`

The thing is, if the whole migration ran then I would be swapping the id column out with another one, and fixing up the foreign keys too. So, is there any way to ignore the constraints for the migration?


Solution

  • Project.connection.disable_referential_integrity do
      Project.delete_all # An example
    end
    

    ActiveRecord::Base.connection.disable_referential_integrity.

    Rails 4.2+.