2009-10-29 62 views
53

我在做這樣的事情在我的遷移:Rails遷移:檢查存在並繼續前進?

add_column :statuses, :hold_reason, :string rescue puts "column already added" 

,但事實證明,而這個工程的SQLite的,它不會對PostgreSQL工作。看起來如果add_column爆炸,即使異常被捕獲,事務已經死亡,所以遷移無法做任何額外的工作。

是否有任何非數據庫特定如何檢查列或表是否已存在?如果沒有,有什麼辦法讓我的救援塊真正起作用嗎?

回答

132

從Rails 3.0及更高版本開始,您可以使用column_exists?來檢查列的存在。

unless column_exists? :statuses, :hold_reason 
    add_column :statuses, :hold_reason, :string 
end 

還有一個table_exists?功能,這可追溯到像Rails 2.1。

+0

是它認爲最好PRACT在添加/創建之前檢查列/表是否存在? (我當然知道這取決於手中的問題) – 2014-04-25 11:11:26

+2

如果我在變化方法中定義它,這是否與回滾一起工作? – dardub 2015-09-18 17:57:35

+0

是回滾將是一個問題...我們不確定是否應該刪除列或因爲我們沒有記錄以前的狀態。 – songyy 2016-07-12 09:26:41

4

對於Rails的2.X,您可以檢查列的存在有以下:

columns("[table-name]").index {|col| col.name == "[column-name]"} 

如果返回零,不存在這樣的列。如果它返回一個Fixnum,那麼該列確實存在。當然,你可以把{...}之間更多的選擇性參數,如果你想的不僅僅是它的名字更多地標識列,例如:

{ |col| col.name == "foo" and col.sql_type == "tinyint(1)" and col.primary == nil } 

(這個答案先貼在How to write conditional migrations in rails?

0

add_column:狀態,:hold_reason,:字符串,除非Status.column_names.include( 「hold_reason」)

5

甚至更​​短的

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason 
+0

這將是對另一個答案的評論,而不是一個答案。謝謝。 – 2013-04-20 15:20:42