2009-10-29 1 views
53

я делал такого рода вещи в моей миграции:Rails Migrations: Проверить существование и продолжить работу?

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

, но оказывается, что, в то время как это работает для SQLite, это не работает для PostgreSQL. Похоже, если add_column взорвется, , даже если Исключение поймано, транзакция мертва, и поэтому Миграция не может выполнять какую-либо дополнительную работу.

Есть ли не-DB sepecific способы проверки наличия столбца или таблицы? В противном случае, есть ли способ, чтобы мой блок спасения действительно работал?

ответ

132

Начиная с Rails 3.0 и более поздних версий, вы можете использовать column_exists?, чтобы проверить наличие столбца.

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

Там также table_exists? функция, которая идет еще в Rails 2.1.

+0

это считается лучшим практ лед, чтобы проверить, существует ли столбец/таблица до добавления/создания? (Я знаю, конечно, это зависит от проблемы в руках) –

+2

Это работает с откатами, если я определяю его в методе изменения? – dardub

+0

Да, откат будет проблемой ... мы не уверены, следует ли удалить столбец или нет .. так как мы не записываем предыдущее состояние. – songyy

4

Для Rails 2.X, вы можете проверить наличие колонок со следующим:

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

Если она возвращает ноль, ни один такой столбец не существует. Если он возвращает Fixnum, то столбец существует. Естественно, вы можете поставить более селективные параметры между {...}, если вы хотите, чтобы определить столбец больше, чем просто его имя, например:

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

(этот ответ первым отвечал на How to write conditional migrations in rails?)

0

add_column: статусы ,: hold_reason,: строка, если Status.column_names.include ("hold_reason")

5

Или еще короче

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

это будет комментарий к другому ответу, а не ответ. Благодарю. –

 Смежные вопросы

  • Нет связанных вопросов^_^