2013-10-01 32 views
1

說我有這個遷移:部分遷移失敗時,爲什麼不「撤消」?

class MigrateStuff < ActiveRecord::Migration 
    def up 
    add_column :contacts, :receive_newsletter, :boolean, :default => false 
    add_index :contacts, :receive_newsletter 

    for t in SomeOtherThing.all 
     #... do stuff in here 
    end 
    end 

    def down 
    #... 
    end 
end 

所以我添加一列和索引。然後,我將一些數據加入新列。如果for循環中的某個部分失敗,會發生什麼情況?列/索引不會被刪除。我嘗試添加這一個交易:

class MoveEmailRecipientsToContacts < ActiveRecord::Migration 
    def up 
    Volunteer.transaction do 
     add_column :contacts, :receive_newsletter, :boolean, :default => false 
     add_index :contacts, :receive_newsletter 

     for t in SomeOtherThing.all 
     #... do stuff in here 
     end 
    end 
    end 

    def down 
    #... 
    end 
end 

所以破例在for塊時,不會將此導致事務回滾?但列和索引仍然存在!

處理這個問題的正確方法是什麼?

+1

MySQL不支持模式的事務更改。 *最簡單*的方法來解決它只是切換到Postgres。它們在很大程度上兼容,特別是如果您使用Arel構建查詢。 – coreyward

+0

很高興知道。那麼,爲什麼耙子/鋼軌不會很聰明,並且撤消了模式更改?我想它可能會變得混亂。 –

回答

0

另一種方式是通過引發ActiveRecord :: Rollback異常手動回滾。

raise ActiveRecord::Rollback 

當你想要回滾。

+0

事務塊中引發的「正常」異常會導致事務回滾嗎? –

+0

沒有其他例外不會回滾 – techvineet

+0

如果它回答你的問題,請投票 – techvineet