Могу ли я выполнить откат с использованием метода change_column в Rails 4 и выше?

#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, в то время как другие действия могут и не выполняться.