Rails миграция для изменения столбца
У нас есть script/generate migration add_fieldname_to_tablename fieldname:datatype
синтаксис для добавления новых столбцов в модель.
В той же строке, у нас есть сценарий / генерировать для изменения типа данных столбца? Или я должен написать SQL прямо в моей миграции?
Я хочу изменить столбец из datetime
в date
,
11 ответов
Я думаю, что это должно работать.
change_column :table_name, :column_name, :date
Вы также можете использовать блок, если у вас есть несколько столбцов для изменения в таблице.
Пример:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
См. Документацию API для класса Table для более подробной информации.
Я не знаю, можете ли вы создать миграцию из командной строки, чтобы сделать все это, но вы можете создать новую миграцию, а затем отредактировать миграцию, чтобы выполнить эту задачу.
Если tablename - это имя вашей таблицы, fieldname - это имя вашего поля, и вы хотите изменить дату с даты на дату, вы можете написать миграцию, чтобы сделать это.
Вы можете создать новую миграцию с помощью:
rails g migration change_data_type_for_fieldname
Затем отредактируйте миграцию, используя change_table:
class ChangeDataTypeForFieldname < ActiveRecord::Migration
def self.up
change_table :tablename do |t|
t.change :fieldname, :date
end
end
def self.down
change_table :tablename do |t|
t.change :fieldname, :datetime
end
end
end
Затем запустите миграцию:
rake db:migrate
Как я обнаружил в предыдущих ответах, для изменения типа столбца необходимо выполнить три шага:
Шаг 1:
Создайте новый файл миграции, используя этот код:
rails g migration sample_name_change_column_type
Шаг 2:
Идти к /db/migrate
папку и отредактируйте файл миграции, который вы сделали. Есть два разных решения.
def change change_column(:table_name, :column_name, :new_type) end
2.
def up
change_column :table_name, :column_name, :new_type
end
def down
change_column :table_name, :column_name, :old_type
end
Шаг 3:
Не забудьте выполнить эту команду:
rake db:migrate
Я проверил это решение для Rails 4, и оно работает хорошо.
С рельсами 5
Если вы хотите, чтобы миграция сделала что-то, что Active Record не знает, как отменить, вы можете использовать
reversible
:
class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
def change
reversible do |dir|
change_table :tablename do |t|
dir.up { t.change :fieldname, :date }
dir.down { t.change :fieldname, :datetime }
end
end
end
end
Просто создайте миграцию:
rails g migration change_column_to_new_from_table_name
Обновите миграцию так:
class ClassName < ActiveRecord::Migration
change_table :table_name do |t|
t.change :column_name, :data_type
end
end
и наконец
rake db:migrate
Все это предполагает, что тип данных столбца имеет неявное преобразование для любых существующих данных. Я столкнулся с несколькими ситуациями, когда существующие данные, скажем, String
может быть неявно преобразован в новый тип данных, скажем, Date
,
В этой ситуации полезно знать, что вы можете создавать миграции с помощью преобразования данных. Лично мне нравится помещать их в мой файл модели, а затем удалять их после того, как все схемы базы данных были перенесены и стабильны.
/app/models/table.rb
...
def string_to_date
update(new_date_field: date_field.to_date)
end
def date_to_string
update(old_date_field: date_field.to_s)
end
...
def up
# Add column to store converted data
add_column :table_name, :new_date_field, :date
# Update the all resources
Table.all.each(&:string_to_date)
# Remove old column
remove_column :table_name, :date_field
# Rename new column
rename_column :table_name, :new_date_field, :date_field
end
# Reversed steps does allow for migration rollback
def down
add_column :table_name, :old_date_field, :string
Table.all.each(&:date_to_string)
remove_column :table_name, :date_field
rename_column :table_name, :old_date_field, :date_field
end
Ты можешь использовать
change_column
за это:
def change
change_column :table_name, :column_name, :new_data_type
end
Чтобы завершить ответы в случае редактирования значения по умолчанию:
В вашей консоли рельсы:
rails g migration MigrationName
В миграции:
def change
change_column :tables, :field_name, :field_type, default: value
end
Будет выглядеть так:
def change
change_column :members, :approved, :boolean, default: true
end
Вы можете написать миграцию и изменить имя столбца следующим образом
def change
change_column :table_name, :column_name, :new_data_type
end
Другой способ изменить тип данных с помощью миграции
Шаг 1: Вам нужно удалить ошибочное имя поля типа данных, используя миграцию
например:
rails g migration RemoveFieldNameFromTableName field_name:data_type
Здесь не забудьте указать тип данных для вашего поля
Шаг 2: Теперь вы можете добавить поле с правильным типом данных
например:
rails g migration AddFieldNameToTableName field_name:data_type
Вот и все, теперь ваша таблица будет добавлена с правильным полем типа данных, Happy ruby coding!