Добавить столбец в таблицу и исправить значение для существующих записей в Rails
Я хочу добавить столбец "payment_type" в таблицу "заказы".
Вот миграция, которая у меня до сих пор:
def change
add_column :orders, :payment_type, :string
end
Я хочу, чтобы этот файл payment_type удерживал значение "normal" для всех записей, которые в настоящее время находятся в БД. Однако не для будущих записей. Я не хочу значения по умолчанию для будущих записей. Как я могу это сделать?
Ответы
Ответ 1
Поскольку вы просто хотите установить значения для существующих записей all, вы можете использовать update_all
, который намного быстрее, чем цикл для всех экземпляров порядка, поскольку он использует только операторы базы данных и не использует " t управляет всеми заказами:
def up
add_column :orders, :payment_type, :string
Order.reset_column_information
Order.update_all(payment_type: 'normal')
end
def down
remove_column :orders, :payment_type
end
update_all
не вызывает никаких проверок или триггеров.
Ответ 2
def change
add_column :orders, :payment_type, :string
Order.all.each do |order|
order.update_attributes(:payment_type => 'normal')
end
end
Ответ 3
Я думаю, что это самый простой способ:
class AddStateToSites < ActiveRecord::Migration[5.1]
def up
add_column :sites, :state, :string, default: :complete # sets default value for existed records
change_column :sites, :state, :string, default: nil # changes default value for next
end
def down
remove_column :sites, :state
end
end
И после этого проверьте его в консоли:
>> Site.last.state
Site Load (0.6ms) SELECT "sites".* FROM "sites" ORDER BY "sites"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> "complete"
>> Site.new.state
=> nil
Ответ 4
Если вы хотите обновить столбец с переносом, то выше ответы являются удивительными,
Но, если вы хотите обновить столбец локально на своей собственной машине, чтобы при совместном использовании кода другие не смогли увидеть обновленный атрибут, просто перейдите в консоль Rails и цикл...
orders = Order.all
orders.each do |o|
o.update_attribute(:payment_type, 'normal')
end
Rails 4
Ответ 5
Как отмечали другие, не стоит полагаться на классы, которые могут быть удалены в будущем, поскольку это тормозит миграцию в этот момент.
Вместо этого я использую для непосредственного выполнения raw mySQL:
execute "UPDATE `orders` SET `payment_type` = 'normal'"