Rails迁移:从字符串转换为枚举

5
如果我的生产数据库中存储的“类型”为字符串,但我想将该列转换为整数以用于枚举,我该怎么办?
我已经在Google和Stack Overflow上搜索了一下,发现我可以使用CAST,但不确定它到底是做什么的。
如果很容易的话,我想使用Rails的枚举功能,否则,也许我应该坚持使用我的字符串模式...
请给予建议!

你能否覆盖属性访问器以便将其读取为字符串,然后设置为枚举类型? - lcguida
2个回答

10

您可以重命名现有列,创建一个名为"types"(整数)的新列,然后编写一个脚本将适当的整数值存储在新列中,最后删除旧列。

迁移将如下所示:

class FixTypes < ActiveRecord::Migration
  def change
    rename_column :table_name, :types, :old_types
    add_column :table_name, :types, :integer
  end
end
然后编写一个脚本,根据"old_types"设置"types"的值:
Model.all.each do |entry|
  entry.types = %w(status1 status2 status3 status4).index(entry.old_types)
  entry.save!
end

然后删除"old_types"列。


1
让我们来重构一下吧!entry.type = %w(status1 status2 status3 ...).index(entry.old_type) - BroiSatse
谢谢@BroiSatse!@Kevin Brown接受答案不会有任何损失 ;) - amit_saxena

0

我曾经遇到过同样的问题,我发现你可以编辑迁移文件,使用你想要用作枚举的值来更新新列。

它应该看起来像这样:

class UpdateColumnNameInTableName < ActiveRecord::Migration[6.1]
  def up
    add_column :table_name, :new_column_name, :integer

    # Define the new enum values and their corresponding integers
    enum_values = {
      value1: 0,
      value2: 1,
      value3: 2
    }

    # Update the existing rows with the corresponding integer values
    execute <<-SQL
      UPDATE table_name SET new_column_name = #{enum_values[:value1]} WHERE column_name = 'value1';
      UPDATE table_name SET new_column_name = #{enum_values[:value2]} WHERE column_name = 'value2';
      UPDATE table_name SET new_column_name = #{enum_values[:value3]} WHERE column_name = 'value3';
    SQL

    # Define the new column as an enum
    change_column :table_name, :new_column_name, :integer, using: 'new_column_name::integer'
    add_index :table_name, :new_column_name
  end

  def down
    remove_column :table_name, :new_column_name
  end
end

希望有帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接