2013-01-10 80 views
0

我有用戶模型和用戶模型has_one個人檔案模型。 另外我有user.phone和user.profile.phone,但我想刪除user.phone,我將只使用user.profile.phone。rails遷移副本並刪除表

之前,我刪除了user.phone,我想複製user.phone到user.profile.phone如果user.phone不blank.Then我會刪除user.phone

例如:

user.phone = 123 
user.profile.phone = 234 

遷移後:

user.phone will be removed 
user.profile.phone = 123 - 234 

,這是什麼目的,適當的遷移?

回答

1

試試這個

class YourMigration < ActiveRecord::Migration 
def self.up 
    User.find_each do |user| 
user.profile.update_attributes(:phone => user.phone) unless user.phone.blank? 
    end 
    remove_column :users, :phone 
end 

def self.down 
    add_column :users, :phone, :string 
end 
end 
+3

您不應該在類似的遷移中使用'Model.all.each do ...'。它會一次將所有5千萬行的行加載到內存中。而是使用'Model.find_each do ...',它一次加載行1000。這個答案首次發佈時並不存在。 – Arcolye

0

如果你的數據庫不是很大,你可以簡單地這樣做:

User.includes(:profile).all.each{ |u| u.profile.phone = u.phone unless u.phone.nil? } 
在控制檯

。或者你可以在你的遷移寫水木清華這樣的:

def change 
    User.includes(:profile).all.each{ |u| u.profile.phone = u.phone unless u.phone.nil? } 
    remove_column :users, :phone 
end 
0
class YourMigration < ActiveRecord::Migration 
    def self.up 
    User.where("phone IS NOT NULL").includes(:profiles).each{ |u| u.profile.phone = u.phone} 
    remove_column :users, :phone 
    end 
    def self.down 
    add_column :users, :phone, :string 
    end 
end 
0

我不喜歡在遷移使用模型,因爲它產生不必要的痛苦:

採取許多在同一個項目上工作的人和你在遷移中使用模型的人都會提交。其他人刪除用戶模型或對模型進行一些驗證並執行提交。當他或其他人嘗試運行遷移時,可能會失敗,因爲您使用的模型不存在或進行一些驗證。

所以我建議在遷移中使用SQL語句。

class SomeMigartion < ActiveRecord::Migration 
    def self.up 
    execute('update profiles p inner join users u on p.user_id = u.id set p.phone = u.phone where u.phone is not null') 
    remove_column :users, :phone 
    end 

    def self.down 
    add_coulmn :users, :phone 
    end 
end