Подтвердить что ты не робот

Добавить столбец в таблицу и исправить значение для существующих записей в Rails

Я хочу добавить столбец "payment_type" в таблицу "заказы".

Вот миграция, которая у меня до сих пор:

def change
  add_column :orders, :payment_type, :string
end

Я хочу, чтобы этот файл payment_type удерживал значение "normal" для всех записей, которые в настоящее время находятся в БД. Однако не для будущих записей. Я не хочу значения по умолчанию для будущих записей. Как я могу это сделать?

4b9b3361

Ответ 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'"