1

我试图更改表的id场是一个uuidRails迁移 - 暂时忽略外键约束?

这里是我的代码:尝试t.remove :id的时候,因为一个外键约束的

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 

这种迁移休息。该错误信息是:

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` 

的事情是,如果整个迁移跑那么我会被交换出去的id柱用另一个,太固定了外键。那么,有没有办法忽略迁移的限制?

+1

尝试第一次投放的约束,则稍后重新加入http://stackoverflow.com/questions/14122031/how-to-remove-constraints-from-my-mysql-table – jvnill

+0

你也可以将uuid设置为主键,并让主动记录知道。 /api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html#method-i-primary_key – jvnill

回答

0

我的最终代码

ifunless语句在那里,因为我编写和测试增量(和失败的迁移仍然有持久的影响)。更主要的是删除外键然后将其添加回到底(删除键不会删除分贝id领域,只有约束。

class AddUuidToProjects < ActiveRecord::Migration[5.0] 
    def up 
    # remove constraint 
    if foreign_key_exists?(:stories, :projects) 
     say("removing foreign key constraints") 

     remove_foreign_key "stories", "projects" 
     remove_foreign_key "images", "projects" 
    end 

    # create UUID id column 
    unless column_exists?(:projects, :id, :string) 
     say("adding UUID column") 

     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, uuid: SecureRandom.uuid) 
     end 

     change_table :projects do |t| 
     t.remove :id 
     t.rename :uuid, :id 
     end 
     execute "ALTER TABLE projects ADD PRIMARY KEY (id);" 
    end 

    # update foreign keys 
    if(Image.first.project_id.is_a? Integer) 
     say("updating foreign keys") 

     # change foreign key fields to STRING(36) 
     change_column :images, :project_id, :string, limit:36, null: false 
     change_column :stories, :project_id, :string, limit:36, null: false 

     Project.all.each do |p| 
     # has_one soi 
     Image.find_by(project: p.old_id).update!(project: p) 

     # has_many stories 
     Snippet.where(project_id: p.old_id).each do |s| 
      s.update!(project: p) 
     end 
     end 
    end 

    # add constraints back 
    unless foreign_key_exists?(:stories, :projects) 
     say("adding foreign key constraints back") 

     add_foreign_key "stories", "projects" 
     add_foreign_key "images", "projects" 
    end 
    end