2016-01-09 121 views
0

Rails應用程序中我做一個比較大規模的重構(在一個特性分支)的去除(和替換)幾個has many :through類型關聯。由於結構變化相對較大,我通過遍歷'through'類中的所有對象並將其替換爲隨後保存的新對象來完成此操作。這比原始SQL更安全(也更容易),雖然速度較慢,但​​這是我願意支付的價格。粗略地遷移看起來是這樣的:軌道4:刪除類(協)會遷移

def up 
    create_table :new_through_table ... 
    OldThroughTable.find_each do |x| 
    # ... data conversion 
    NewThroughTable.create(...) 
    end 
    drop_table :old_through_table 
end 

def down 
    # vice versa 
end 

在這個變化的過程中,我在app/models創建新類和舊的關聯類現在都是多餘的,一旦遷移完成,所以我刪除的類文件和has_manybelongs_to代碼行中的相關類並提交結果。

但是,由於舊的關聯類現在不存在了,因此任何牽扯我的更改的人都無法運行遷移,因爲舊的類文件不見了,舊的數據庫結構不再映射到新的類結構。

我可以 - 理論上 - 寫在遷移到不需要任何類(原始SQL),但是這似乎麻煩我 - 加,我錯過任何確認和回調的類都有。我也可以將舊的類文件和關聯留在那裏,但我不太喜歡這個想法。

是否有在兩個方向上寫這樣的遷移因此它可以可靠地同時保持代碼乾淨的任何其他清潔的方式?

+0

你確認這個類的一個實例drop_table?我認爲我從來沒有遇到這個問題,儘管它過去一直關注我。 直接在你的數據庫上創建一個'測試'表(不是通過你的應用程序,所以不會有模型定義)。使用「drop_table:test」創建遷移,如果有效,那麼您應該很好。 –

+0

這不是drop_table命令,它是遷移過程中的數據轉換,它需要循環舊模型和新模型。我添加了一個例子。 – Jens

回答

1

一種方法是把模型,遷移需要他們,到遷移,即

class SomeMigration < ActiveRecord::Migration 
    class SomeModel < ActiveRecord::Base 
    ... 
    end 

    def up 
    SomeModel.find_each do |record| 
     ... 
    end 

    drop_table :some_models 
    end 
end 

您將需要複製任何關聯或驗證你想遷移到使用。您最終將獲得更大的遷移,但您確切知道遷移正在使用的是哪種模型代碼,而不是運行遷移的最新代碼。

+0

這可能確實有效。我會盡快嘗試。謝謝! – Jens

+0

它曾經被記錄 - http://guides.rubyonrails.org/v4.1/migrations.html#using-models-in-your-migrations –