【问题标题】:How can I realise "Write to both columns" in Rails Active Record (as Strong migrations recommends)?如何在 Rails Active Record 中实现“写入两列”(如强迁移建议的那样)?
【发布时间】:2020-11-27 10:41:47
【问题描述】:

我正在尝试更改 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 模型同时写入两列并在回填后切换到正确的列?

【问题讨论】:

    标签: ruby-on-rails postgresql rails-activerecord rails-migrations


    【解决方案1】:

    假设旧列是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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多