在 Rails 迁移中将数据从已删除的列移动到刚创建的列
Move data from removed column to just created one in Rails migration
我有一个 table 'Invoices',其中包含两个布尔列:
Table name: invoices
id :integer not null, primary key
...
sent :boolean default(FALSE)
payment_received :boolean default(FALSE)
这两列定义了发票的状态:
def status
if sent & payment_received
:paid
elsif sent | payment_received
:sent
else
:created
end
end
有一天,在 Rails enum
的帮助下,决定删除这些布尔列并创建将包含发票状态的新列
status :integer
enum status: [ :created, :sent, :paid ]
所以现在我需要做三件事:
- 添加新列 'status'
- 计算现有发票的状态,更新状态列
- 删除列 'sent' 和 'payment_received'。
我该怎么做?我可以在本地环境中轻松完成此任务,但我不明白如何在生产服务器上执行此任务。例如,如果我将创建一个更新我的 table 的迁移和一个计算状态的 rake 任务,迁移首先通过并且我的布尔列中的数据将在我可以使用它们之前被删除。
注意:如果不知何故重要:我使用 Postgres。
感谢任何帮助!
尝试以下迁移。
class UpdateInvoicesTable < ActiveRecord::Migration
def self.up
add_column :invoices,:status,:string
Invoice.find_in_batches(batch_size: 2000) do |invoices|
invoices.each do |invoice|
if invoice.sent & invoice.payment_received
invoice.status = 'paid'
elsif invoice.sent | invoice.payment_received
invoice.status = 'sent'
else
invoice.status = 'created'
end
invoice.save
end
end
remove_column :invoices,:sent
remove_column :invoices,:payment_received
end
end
我有一个 table 'Invoices',其中包含两个布尔列:
Table name: invoices
id :integer not null, primary key
...
sent :boolean default(FALSE)
payment_received :boolean default(FALSE)
这两列定义了发票的状态:
def status
if sent & payment_received
:paid
elsif sent | payment_received
:sent
else
:created
end
end
有一天,在 Rails enum
的帮助下,决定删除这些布尔列并创建将包含发票状态的新列status :integer
enum status: [ :created, :sent, :paid ]
所以现在我需要做三件事:
- 添加新列 'status'
- 计算现有发票的状态,更新状态列
- 删除列 'sent' 和 'payment_received'。
我该怎么做?我可以在本地环境中轻松完成此任务,但我不明白如何在生产服务器上执行此任务。例如,如果我将创建一个更新我的 table 的迁移和一个计算状态的 rake 任务,迁移首先通过并且我的布尔列中的数据将在我可以使用它们之前被删除。
注意:如果不知何故重要:我使用 Postgres。
感谢任何帮助!
尝试以下迁移。
class UpdateInvoicesTable < ActiveRecord::Migration
def self.up
add_column :invoices,:status,:string
Invoice.find_in_batches(batch_size: 2000) do |invoices|
invoices.each do |invoice|
if invoice.sent & invoice.payment_received
invoice.status = 'paid'
elsif invoice.sent | invoice.payment_received
invoice.status = 'sent'
else
invoice.status = 'created'
end
invoice.save
end
end
remove_column :invoices,:sent
remove_column :invoices,:payment_received
end
end