2010-01-25 34 views
2

所以我的用戶模型和相應的表(用戶)與先前場創建的數據:USER_ID,用戶名,密碼等添加新的領域,以預先存在的表並修改Rails的

但後來我加入用戶表的invitation_limit。新創建的用戶具有invitation_limit,但在運行invitation_token遷移之前創建的用戶沒有invitation_limit字段。

如何更新之前創建的用戶以包含invitation_token字段?請注意,我並不是在向用戶表添加invitation_limit字段(即遷移),而是更新已經創建的用戶。

謝謝,

回答

4

種子數據不應該被放在一個遷移。遷移是爲了創建結構,而不是添加數據,如果您移動數據庫,則會遇到問題。

你可以寫一個rake任務。如果你創建了一個名爲類似「generate_invitation_token」實例方法,你就可以寫一耙的任務是這樣的:

# lib/tasks/invitation_tokens.rake 
namespace :seed do 
    desc "generate invitation tokens for users that don't have one already" 
    task :user_tokens => :environment do 
    User.all(:conditions => {:invitation_token => nil}).each do |user| 
     user.generate_invitation_token 
    end 
    end 
end 

然後,您可以從命令行調用rake任務是這樣的:

rake seed:user_tokens 

這是一個更乾淨的方式來做到這一點。

UPDATE

我已經擴大了在所謂的 「Adding Columns and Default Data To Existing Models」 博客帖子這個答案。

+0

這就是我正在尋找的,謝謝! – 2010-01-25 07:19:53

1

不幸的是,通常接受的策略是添加另一個填充這些字段的遷移。當然,您不能使用活動記錄(或者您的遷移可能會中斷),因此最佳做法是在pure SQL中執行此操作。

+0

我明白了。這是否工作? User.find(:all).each do | p | p.update_attribute:invitation_limit,5 end – 2010-01-25 07:09:18

+0

這會起作用,但這不是我在答案中提到的最佳做法,因爲它引用了一個模型,嚴格來說,這個模型在將來可能會被刪除或重命名,從而導致您的遷移失敗。 – tfwright 2010-01-25 07:11:22

+0

謝謝,我將使用上面提到的rake任務。 – 2010-01-25 07:20:23

0

您想爲此使用遷移。遷移只是ruby代碼,因此您可以訪問應用程序有權訪問的所有數據。更改數據,添加缺少的數據,刪除行等

一些快速提示:

1

我的理解是你要更新用戶記錄,而不是創建種子(種子添加數據到你的數據庫,例如角色等等,這對你的應用程序很重要)。從documentaion

class AddReceiveNewsletterToUsers < ActiveRecord::Migration 
    def self.up 
    change_table :users do |t| 
     t.boolean :receive_newsletter, :default => false 
    end 
    User.update_all ["receive_newsletter = ?", true] 
    end 

    def self.down 
    remove_column :users, :receive_newsletter 
    end 
end 

你也可以用你的模型內遷移:

User.all(:conditions => {}).each do |user| 
    user.do_sth 
    user.save 
end 

等,閱讀about caveats

編輯:
您的評論後,這是我認爲你應該在移民中做到這一點;

class AddInvitationLimitToUser < ActiveRecord::Migration 
    def selt.up 
    change_table :users do |t| 
     t.integer :invitation_limit # and add validation to model `validates_presence_of` and so on 
    end 
    # now update all records already in database, which didn't had value in invitation_limit column 
    User.update_all ["invitation_limit = ?", 5] 
    end 

    def self.down 
    remove_column, :users, :invitation_limit 
    end 
end 
+0

嗯,我想創建用戶後,添加一個新的字段到我的用戶表。我創建了用戶模型,然後在users表中添加了invite_limit字段,所以在遷移新字段之前創建的用戶將不會擁有新字段。我想更新這些用戶,並添加invitation_limit並將它們設置爲5. – 2010-01-25 11:44:52

+0

@Senthil用戶在遷移新字段之前創建新字段,它們只有沒有值(默認情況下它將爲NULL)。他們在同一張表中,您已經修改過,所以他們不能錯過新的字段(列),因爲它們是早先創建的。 – MBO 2010-01-25 12:58:37

+0

你是對的,它確實被創建。我想我以前得到的錯誤是它說它是NULL,而不是它沒有創建。謝謝! – 2010-01-26 06:06:19