2011-05-20 110 views
4

我的Rails 3應用程序有一個User模型和一個Profile模型。 A用戶has_one配置文件。Rails 3:遷移數據

當前配置文件具有屬性first_namelast_name。雖然我不知道爲什麼你可能想要改變它們,但我原本以爲這些應該是可以改變的,所以我把它們放在Profile模型而不是User模型中。

但是,隨着應用程序的發展,我發現實際上我需要不改變用戶的名字和姓氏,而且我真的需要他們成爲用戶模型的一部分而不是配置文件模型。

所以,我想知道,你可以寫一個遷移會:

  1. 添加first_namelast_name列到用戶模式。
  2. 從關聯的配置文件記錄中獲取給定用戶的現有first_namelast_name值,並將其複製到用戶模型中。
  3. 從Profile模型中刪除first_namelast_name列,因爲它們不再需要。

那麼,可以這樣做嗎?你能舉一個例子嗎?而且,最重要的是,我應該注意哪些問題?我想將此更改應用到生產應用程序,因此,在進行此更改時,我不會丟失數據,這一點至關重要。

謝謝!

+0

我有點好奇爲什麼'User'模型不允許改變這些屬性,而'Profile'模型會改變。在這些情況下真的不應該有所不同,除非您明確指定哪些屬性可以訪問。 – raidfive 2011-05-20 01:39:19

+0

哦,他們都可以允許或不允許更改 - 我只是在用戶模型中將事物分組爲「永久」(即,我不讓用戶更改它們),並且配置文件中的所有內容都是「非永久性的「(即我允許用戶改變它們)。但是我發現我越來越需要使用用戶的名字和姓氏作爲文件標識符的一部分,這些文件標識符確實無法更改,所以對於我而言,我寧願將其與更靜態的用戶屬性進行分組。 – Andrew 2011-05-20 01:41:26

回答

13

當然,非常方便。把這個在遷移:

add_column(:users, :last_name, :string) 
    add_column(:users, :first_name, :string) 

    User.reset_column_information 

    User.all.each do |u| 
     u.last_name = u.profile.try(:last_name) 
     u.first_name = u.profile.try(:first_name) 
     u.save 
    end 

    remove_column(:profiles, :first_name) 
    remove_column(:profiles, :last_name) 

我用try()來緩解一個缺少配置文件的可能性。它不檢查保存操作中的錯誤,因此如果您認爲需要,請考慮這一點。此外,一如既往,在運行數據庫轉儲備份之前進行備份。 :)

+0

這太棒了!謝謝! – Andrew 2011-05-20 17:58:13