ruby-on-rails - 如何在 Rails Active Record 中实现“写入两列”(如 Strong 迁移所建议的那样)?
问题描述
我正在尝试更改 PostgreSQL (Rails 6) 中的列类型。
移民:
# frozen_string_literal: true
class ChangeUsersEmailToCitext < ActiveRecord::Migration[6.0]
def up
enable_extension('citext')
change_column :users, :email, :citext
end
def down
change_column :users, :email, :string
end
end
但是 Strong Migrations 抛出错误并显示以下内容:
=== Dangerous operation detected #strong_migrations ===
Changing the type of an existing column blocks reads and writes
while the entire table is rewritten. A safer approach is to:
1. Create a new column
2. Write to both columns
3. Backfill data from the old column to the new column
4. Move reads from the old column to the new column
5. Stop writing to the old column
6. Drop the old column
我了解数据库锁定的意义和危险......但我的问题很愚蠢,我还没有找到答案。从字面上看,我如何才能获得第 2、第 4 和第 5 分?如何强制我的 ActiveRecord 模型同时写入两列并在回填后切换到正确的列?
解决方案
假设旧列是length
,新列是length_advanced
。
2 - 写入两列
def length=(value)
super(value)
self[:length_advanced] = value
end
4 - 将读取从旧列移动到新列
def length
if super.present?
super
else
self[:length_advanced]
end
end
5 - 停止写入旧列
def length=(value)
# no write to old column
self[:length_advanced] = value
end
有关所有这些的更多信息https://api.rubyonrails.org/classes/ActiveRecord/Base.html