2010-12-04 128 views
0

我將我的數據庫中的關係從has_many更改爲has_many:through。所以現在我有:通過db:migrate更改結構數據庫後,Rails如何執行數據更新?

class Brand < Ar::Base 
    has_many :products 
end 

class Product < AR::Base 
    belongs_to :brand 
end 

我打算添加一個連接表。

但是當然我需要用數據更新數據庫。我已經看到,在遷移的範圍內這樣做並不是一個好習慣。在數據更新完成後(即從產品表中刪除原始brand_id列),我知道必須在數據更新完成後再運行另一次遷移,這是執行此操作的最佳位置?

回答

2

除非我誤解了你的問題,否則遷移是進行轉換的地方。遷移的目的是更改模式並遷移現有數據以使用模式。遷移捕獲分層模式更改的時間方面,以便您可以及時前進和後退,而不會使數據處於不一致的狀態。如果您要在其他地方遷移行,則無法保證在代碼運行時架構與您編寫遷移代碼時的架構相同。

我相信你會在Active Record Migrations api文檔的例子中找到對我的立場的支持。您可能會將遷移與填充的種子數據混淆(rake db:seed),這是在db/seeds.rb中處理的。

+0

看起來他想運行遷移(添加連接表),然後操作表中的數據,然後再運行另一個遷移。種子是爲了傳播最初的數據而添加的,但這不是他想要達到的目標......他想操縱現有的數據。有些人認爲你不應該用遷移來操縱表中的數據,只能使用表本身。 – johnmcaliley 2010-12-04 20:56:50

+1

我會爭辯說,這樣做的正確位置應該在一次遷移中。運行與首次遷移相關的更改,遷移數據,然後運行其餘的更改。如果這三個步驟相互聯繫,那麼任何一個都不應該獨立發生,它們應該包含在一個遷移中。 – 2010-12-04 21:09:22

1

我認爲您至少應該包含對遷移中運行數據操作的代碼(可能是rake任務)的調用,因爲您必須在數據操作後立即運行第二次遷移。

如果是我,我會創建一個操縱數據的rake任務。這將至少從遷移中刪除代碼,並允許您在必要時手動運行代碼。然後編寫您的遷移代碼幷包含對該rake任務的調用。我真的不明白在遷移中不使用數據操作的重大問題。尤其是當你必須按照特定的順序做事情時。他們緊緊地綁在一起,爲什麼要將他們徹底分開?

2

像這樣的一次性更改可以在遷移中使用ruby代碼完成。遷移不僅適用於模式更改。這個想法是,通過版本/日期代碼確保遷移只能運行一次。