Rails迁移:检查存在和继续?

我在迁徙中做了这样的事情:

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

但事实certificate, 虽然这适用于SQLite,但它不适用于PostgreSQL 。 看起来如果add_column爆炸, 即使Exception被捕获,事务也是死的,所以迁移不能做任何额外的工作。

有没有非数据库特定的方式来检查列或表是否已经存在? 如果没有,有没有办法让我的救援块真正的工作?

从Rails 3.0和更高版本,你可以使用column_exists? 检查列的存在。

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

还有一个table_exists? 函数,可以追溯到Rails 2.1。

对于Rails 2.X ,你可以检查列的存在与以下几点:

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

如果返回nil,则不存在这样的列。 如果它返回一个Fixnum,那么列确实存在。 当然,如果你想用不止一个名字来标识一列,你可以在{...}之间join更多的select性参数,例如:

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

(这个答案首先张贴在如何写条件迁移在轨道? )

甚至更短

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

add_column:status,:hold_reason,:string除非Status.column_names.include?(“hold_reason”)