web-dev-qa-db-ja.com

Rails移行:存在を確認し、続行しますか?

私は移行でこの種のことをしていました:

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

しかし、判明したのは、これはSQLiteでは機能しますが、PostgreSQLでは機能しませんです。 add_columnが爆発した場合、例外がキャッチされた場合でもトランザクションは停止しているため、Migrationは追加の作業を行えません。

列またはテーブルが既に存在するかどうかを確認する非DB固有の方法はありますか?それに失敗すると、私のレスキューブロックを実際に機能させる方法はありますか?

69
Dan Rosenstark

Rails 3.0以降では、 column_exists? 列の存在を確認します。

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

table_exists? 関数。これは、Rails 2.1。

156
Tobias Cohen

またはさらに短く

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
7
SG 86

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で条件付き移行を書く方法? に投稿されました)

4
JellicleCat

add_column :statuses, :hold_reason, :string unless Status.column_names.include?("hold_reason")

0
Denis Neverov