Рельсы миграции: проверить существование и продолжать идти?
Я делал такие вещи в моих миграциях:
add_column :statuses, :hold_reason, :string rescue puts "column already added"
но оказывается, что,хотя это работает для SQLite, он не работает для PostgreSQL. Кажется, что если add_column взрывается,даже если исключение перехватывается, транзакция мертва, и поэтому миграция не может выполнять никакой дополнительной работы.
есть non-DB sepecific способы проверить, если столбец или таблица уже существуют? В противном случае, есть ли способ чтобы мой спасательный блок действительно работал?
4 ответа:
начиная с Rails 3.0 и более поздних версий, вы можете использовать
column_exists?
для проверки наличия столбца.unless column_exists? :statuses, :hold_reason add_column :statuses, :hold_reason, :string end
есть еще
table_exists?
функция, которая идет еще до рельсов 2.1.
или еще короче
add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
на рельсы 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?)