dei*_*iga 6 migration activerecord ruby-on-rails ruby-on-rails-2
我的模型(酒吧)已经有一个参考列,我们称之为foo_id,现在我需要改变foo_id,以fooable_id使之多态性.
我想我有两个选择:
fooable多态的新参考列并从中迁移ID foo_id (迁移这些的最佳方法是什么?我可以做吗?Bar.each { |b| b.fooable_id = b.foo_id }?foo_id到fooable_id并添加polymorphic到fooable_id.如何将多态添加到现有列?Chr*_*lle 15
1.更改名称foo_id到fooable_id在像迁移重命名它:
rename_column :bars, :foo_id, :fooable_id
Run Code Online (Sandbox Code Playgroud)
2.通过在迁移中添加所需的foo_type列,为其添加多态性:
add_column :bars, :fooable_type, :string
Run Code Online (Sandbox Code Playgroud)
3.并在您的模型中:
class Bar < ActiveRecord::Base
belongs_to :fooable,
polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)
4.最后种子你已经关联的类型如:
Bar.update_all(fooable_type: 'Foo')
Run Code Online (Sandbox Code Playgroud)
Mar*_*n M 10
Rails 更新 >= 4.2
当前的 Rails 生成带有索引和外键的引用,这是一件好事。
这意味着@Christian Rolle 的答案不再有效,因为在重命名后foo_id它会在bars.fooable_id引用时留下一个外键,foo.id这对其他fooables无效。
幸运的是,迁移也在发展,因此确实存在可撤销的引用迁移。
您需要创建一个新的引用并删除旧的引用,而不是重命名引用 ID。
新的是需要将旧引用中的 id 迁移到新引用。
这可以通过一个
Bar.find_each { |bar| bar.update fooable_id: bar.foo_id }
Run Code Online (Sandbox Code Playgroud)
但是当已经有很多关系时,这可能会很慢。Bar.update_all在数据库级别执行此操作,速度要快得多。
当然,你应该能够回滚迁移,所以当使用 foreign_keys 时,完整的迁移是:
def change
add_reference :bars, :fooable, polymorphic: true
reversible do |dir|
dir.up { Bar.update_all("fooable_id = foo_id, fooable_type='Foo'") }
dir.down { Bar.update_all('foo_id = fooable_id') }
end
remove_reference :bars, :foo, index: true, foreign_key: true
end
Run Code Online (Sandbox Code Playgroud)
请记住,在回滚期间,更改是从下到上处理的,因此 foo_id 在 之前创建update_all,一切正常。
| 归档时间: |
|
| 查看次数: |
4744 次 |
| 最近记录: |