2011-06-12 57 views
2

我在Ruby on Rails中理解遷移有點麻煩。我在我的應用程序的db\migrate\目錄下面的兩個類(保存在單獨的文件):Rails - 理解db:migrate

class CreateUsers < ActiveRecord::Migration 
    def self.up 
    create_table :users do |t| 
     t.string :name 
     t.string :email 

     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :users 
    end 
end 

class AddEmailUniquenessIndex < ActiveRecord::Migration 
    def self.up 
    add_index :users, :email, :unique => true 
    end 

    def self.down 
    remove_index :users, :email 
    end 
end 

我在這兩個文件是如何似乎是一起運行困惑。在創建第二課時,Michael Hartl的書中說:「我們可以編輯用戶表的遷移文件,但這需要回滾,然後再遷移回來。Rails Way每次發現我們的數據時都會使用遷移模型需要改變。「這些遷移如何實際工作?數據庫遷移時目錄中的所有文件是否都運行?就像幕後發生的事情一樣?

回答

7

作爲約定,這些遷移類的文件名將以時間戳爲前綴表示何時創建(例如20110611000000)。當您運行db:migrate時,rails將檢查數據庫中的一個特殊表,其中包含應用於數據庫的上次遷移的時間戳。然後,它將在該日期之後應用具有時間戳的所有遷移,並使用上次遷移的時間戳更新數據庫表。因此,每個遷移類只能應用一次到數據庫。

邁克爾·哈特正在說明,如果你把所有的遷移都放到一個單獨的文件中,那麼rails會有一個難以/不可能的時間來告訴哪些遷移已經被應用,哪些沒有被遷移。此時唯一的選擇是刪除數據庫中的所有表並從頭開始執行所有遷移。功能上可行,但你會丟失所有數據。最好只在'前進'方向上移動,而不是回到開始,然後再前進。

+4

'當您運行db:migrate時,rails會檢查數據庫中的一個特殊表,其中包含應用於數據庫的最後一次遷移的時間戳。表名是'schema_migrations',它將存儲已經運行的遷移文件的時間戳。 – rubyprince 2011-06-12 04:57:19

2

它基本上是SQL接口的編程前端。它使您不必直接與數據庫進行交互,並確保您可以使用任何數據庫類型(mySQL,SQLite,PostOgre)

4

這些遷移如何實際工作?

db:migrate是一個rake任務。 db:migrate任務(內置的Rails支持程序)將搜索項目的db/migrate目錄並使用其中的文件更新數據庫的模式。

當遷移數據庫時,目錄中的所有文件都運行嗎?不可以。只有在命令行中輸入「rake db:migrate」時,纔會運行新的db/migrate文件(自上次運行db:migrate命令後添加的那些文件)。

這意味着修改任何db/migrate文件是一個壞主意(不是Rails方式)。相反,請添加一個新文件。

像這裏幕後發生的事情? Rails和db:migrate機器如何跟蹤項目的db版本取決於Rails的版本。

加入:這裏是一些good info關於遷移如何在掩護下工作。

3

將每個文件視爲一組要運行一次的指令。基本上rake db:migrate任務將加載遷移對象並在其上運行.up()。如果您已經運行遷移,那麼更改文件不再有任何影響 - 遷移已經運行。但是,更改遷移可能會導致應用程序的其他用戶無法使用。所以,不要改變舊的遷移,創建新的遷移,然後只運行一次。

因爲遷移類只有在你真的可以刪除舊的遷移文件時纔會被執行,但如果你重置了你的數據庫,你需要運行rake db:setup第一次在rake db之前:migrate(基本上數據庫將需要首先從schema.rb文件加載,因爲您的遷移將不再包含使數據庫進入最終狀態所需的所有步驟)。這些文件並不佔用太多空間,所以通常情況下讓它們保持獨立更簡單。