私は移行でこの種のことをしていました:
add_column :statuses, :hold_reason, :string rescue puts "column already added"
しかし、判明したのは、これはSQLiteでは機能しますが、PostgreSQLでは機能しませんです。 add_columnが爆発した場合、例外がキャッチされた場合でもトランザクションは停止しているため、Migrationは追加の作業を行えません。
列またはテーブルが既に存在するかどうかを確認する非DB固有の方法はありますか?それに失敗すると、私のレスキューブロックを実際に機能させる方法はありますか?
Rails 3.0以降では、 column_exists?
列の存在を確認します。
unless column_exists? :statuses, :hold_reason
add_column :statuses, :hold_reason, :string
end
table_exists?
関数。これは、Rails 2.1。
またはさらに短く
add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
Rails 2.Xの場合、以下を使用して列の存在を確認できます。
columns("[table-name]").index {|col| col.name == "[column-name]"}
Nilを返す場合、そのような列は存在しません。 Fixnumを返す場合、列は存在します。当然、名前だけでなく列を識別する場合は、{...}
の間により選択的なパラメーターを配置できます。例:
{ |col| col.name == "foo" and col.sql_type == "tinyint(1)" and col.primary == nil }
(この回答は最初に Railsで条件付き移行を書く方法? に投稿されました)
add_column :statuses, :hold_reason, :string unless Status.column_names.include?("hold_reason")