【问题标题】:How to migrate the database when renaming an ActiveRecord model that is a subclass of a base class?重命名作为基类子类的 ActiveRecord 模型时如何迁移数据库?
【发布时间】:2012-07-11 14:17:36
【问题描述】:

当模型使用单表继承 (STI) 存储在数据库中时,如何编写 Rails 迁移来重命名 ActiveRecord 子类?我唯一能想到的就是使用原始的 sql 更新语句将类型列值的值从旧的子类型名称更改为新的。

【问题讨论】:

  • 您是否要重命名存储在type 列中的字符串文本?

标签: ruby-on-rails activerecord


【解决方案1】:

您可以使用execute 在迁移中运行原始查询

class YourMigration < ActiveRecord::Migration
  def up
    execute "UPDATE table_name SET type = 'Namespace::NewSubclass' WHERE type = 'Namespace::OldSubclass'"
  end

  def down
    execute "UPDATE table_name SET type = 'Namespace::OldSubclass' WHERE type = 'Namespace::NewSubclass'"
  end
end

【讨论】:

  • 看起来上下查询应该在这里交换。
  • up 在迁移序列中向前移动。 down 向后移动。
  • 我的意思是 up 方法应该运行 execute "UPDATE table_name SET type = 'Namespace::NewSubclass' WHERE type = 'Namespace::OldSubclass'"
  • 谢谢,我更新了答案。抱歉太密集了!
【解决方案2】:

Rails 4 允许您为 @deefour 的回答定义 reversible 迁移:

def change
  rename_sti_type :table_name, 'Namespace::OldSubclass', 'Namespace::NewSubclass'
end

def rename_sti_type(table_name, old_type, new_type)
  reversible do |dir|
    dir.up { execute "UPDATE #{table_name} SET type = '#{new_type}' WHERE type = '#{old_type}'" }
    dir.down { execute "UPDATE #{table_name} SET type = '#{old_type}' WHERE type = '#{new_type}'"}
  end
end

您可以将其概括为change_data(table, field, old_value, new_value) 方法;但请注意,如果向上迁移将类型/字段设置为已在使用的new_value,那么向下迁移也会将已经具有new_value 值的现有行更改为old_value

【讨论】:

    猜你喜欢
    • 2020-01-13
    • 2010-10-03
    • 1970-01-01
    • 2013-01-25
    • 2015-11-07
    • 2010-12-15
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多