#ruby-on-rails #ruby-on-rails-4 #ruby-on-rails-5 #rails-activerecord #rails-migrations
#ruby-on-rails #ruby-on-rails-4 #ruby-on-rails-5 #rails-activerecord #rails-миграции
Вопрос:
Может ли change_column
метод выполнять откат, когда он используется при миграции в Rails 4 и выше?
Вот пример:
def change
change_column etc
end
Должен ли я вместо этого использовать методы up
и down
?
Комментарии:
1. Нет, вы должны просто использовать
up
иdown
. Чистый и понятный, особенно для тех, кто работает с Rails с версий 2 и 3.
Ответ №1:
change_column
по умолчанию отменить невозможно. Rails не может знать определение столбца до миграции, поэтому он не может выполнить откат к этому исходному определению.
Поэтому, начиная с Rails 4, вы можете предоставить Rails необходимую информацию. Для этого и предназначен обратимый метод:
def change
reversible do |dir|
dir.up do
change_column :users, :score, :decimal, precision: 6, scale: 2
end
dir.down do
change_column :users, :score, :decimal, precision: 4, scale: 2
end
end
end
На первый взгляд это кажется более сложным, чем использование up
и down
. Преимущество в том, что вы можете смешивать его с обратимыми миграциями.
Если, например, вы добавляете кучу полей в таблицу и вам приходится изменять несколько полей вместе, вы можете использовать change_table
и add_column
вместе с reversible
для обеспечения чистой и компактной миграции:
def change
change_table :users do |t|
t.string :address
t.date :birthday
# ...
end
reversible do |dir|
dir.up do
change_column :users, :score, :decimal, precision: 6, scale: 2
end
dir.down do
change_column :users, :score, :decimal, precision: 4, scale: 2
end
end
end
Комментарии:
1. Спасибо, я попытался выполнить откат с помощью change_column, и rails говорят, что: В этой миграции используется change_column, который не является автоматически обратимым.
2. Является ли ответ на исходный вопрос ОТРИЦАТЕЛЬНЫМ?
3. буквально ответ на исходный вопрос должен ли я вместо этого использовать методы up и down? это ДА … и есть еще варианты.
Ответ №2:
Возможно выполнить откат миграции с помощью change_columns в rails 4 или rails 5 с:
def change end
Да, можно выполнить откат миграции с помощью empty (а также корректного непустого) change
метода.
Когда у вас действительно что-то есть, вы, возможно, не сможете отменить миграцию, например, с помощью remove_column
, если вы не указали тип столбца, который вы удалили.
Также, если, например, у вас есть метод change_column
in change
. Как Rails должен узнать, какой тип / имя / что бы там ни было у столбца было до изменения, если не из down
метода? 🙂
Итак, если вы планируете выполнять откат назад и вперед, вы хотели бы быть как можно более явным, поэтому использование up
и down
— очень хорошая (на самом деле лучшая) идея.
Комментарии:
1. Я не очень хорошо выразился, я обновил вопрос
2. @MatheusSilva, может быть, ты этого не делал, но я думаю, что сделал 🙂 Я рекомендовал использовать up / down привел пример того, почему just
change
не идеален3. Спасибо. Я видел, что новые версии Rails могут возвращаться при удалении или переименовании изменения, но я не нашел об change_column.
4. @MatheusSilva более старые версии могли отменить удаление (которое я использовал в своем примере), но только если вы укажете тип столбца. Попробуйте вернуть значение remove_column без указанного типа, насколько я помню, вы не сможете этого сделать. Кроме того, наличие
up
иdown
более явно для людей, которые видят миграцию впервые, поэтому я голосую за преимущественное использованиеup
/down
Ответ №3:
Вы также можете использовать
change_column_null(table_name, column_name, null, default = nil)
Чтобы сохранить некоторый код. Activerecord знает, как выполнить откат этого.
Ответ №4:
РЕДАКТИРОВАТЬ: Я просто хочу извиниться за то, что так долго обновлял этот ответ, я изначально не понял вопроса.
Когда вы пишете миграцию в Rails, у вас есть два подхода, которые вы можете использовать: вы можете использовать change
или up
down
подход. При использовании change важно быть в курсе того, что делает ваша миграция, потому что change
конструкция попытается определить, каким будет противоположное действие в случае, если вам придется откатить миграцию. Такие методы миграции, как add_column
, add_index
, create_table
и т.д., Имеют противоположные действия, которые rails может вывести. Миграция, подобная change_column
однако, может быть буквально любой, поэтому, как сказал Мартин, вам нужно будет включить reversible
блок, чтобы rails знал, что делать, когда возврат может быть неоднозначным.
Комментарии:
1. Не совсем, если я попытаюсь выполнить откат с помощью предупреждений об изменении столбца rails: в этой миграции используется change_column, который не является автоматически обратимым.
2. Да, это зависит от того, что делается в операторе изменения, например, добавление столбца имеет обратимое действие, которое понимает rails, в то время как другие действия могут и не выполняться.