Я делал такие вещи в своих миграциях:
add_column :statuses, :hold_reason, :string rescue puts "column already added"
но оказывается, что, хотя это работает для SQLite, это не работает для PostgreSQL . Похоже, что если add_column взорвется, даже если исключение перехвачено , транзакция мертва, и поэтому миграция не может выполнять дополнительную работу.
Есть ли какие -либо способы, не связанные с БД, чтобы проверить, существует ли уже столбец или таблица? Если это не удается, есть ли способ заставить мой спасательный блок действительно работать?
ruby-on-rails
migration
Дэн Розенстарк
источник
источник
Ответы:
Начиная с 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 }
(этот ответ впервые был опубликован в разделе Как писать условные миграции в рельсах? )
источник
add_column :statuses, :hold_reason, :string unless Status.column_names.include?("hold_reason")
источник