【发布时间】:2012-07-11 14:17:36
【问题描述】:
当模型使用单表继承 (STI) 存储在数据库中时,如何编写 Rails 迁移来重命名 ActiveRecord 子类?我唯一能想到的就是使用原始的 sql 更新语句将类型列值的值从旧的子类型名称更改为新的。
【问题讨论】:
-
您是否要重命名存储在
type列中的字符串文本?
标签: ruby-on-rails activerecord
当模型使用单表继承 (STI) 存储在数据库中时,如何编写 Rails 迁移来重命名 ActiveRecord 子类?我唯一能想到的就是使用原始的 sql 更新语句将类型列值的值从旧的子类型名称更改为新的。
【问题讨论】:
type 列中的字符串文本?
标签: ruby-on-rails activerecord
您可以使用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'"
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。
【讨论】: