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