【问题标题】:Rails inheritance_column migrationRails 继承_列迁移
【发布时间】:2016-10-08 16:24:15
【问题描述】:

我正在更改现有应用程序中使用 STI 扩展的基本模型的 inheritance_column 值。如何编写迁移以使现有列符合新的inheritance_column

这是我的第一次尝试:

class MigrateStoryTypes < ActiveRecord::Migration

  def self.up
    Story.all.each { |story|
      new_story_type = story.story_type.camelize + 'Story'
      puts "changing #{story.id}'s story_type from #{story.story_type} to #{new_story_type}"
      story.update_column :story_type, new_story_type
    }
  end

  def self.down
    Story.all.each { |story|
      new_story_type = story.story_type.underscore.gsub /_story/, ''
      puts "changing #{story.id}'s story_type from #{story.story_type} to #{new_story_type}"
      story.update_column :story_type, new_story_type
    }
  end

end

但是,这失败了:

ActiveRecord::SubclassNotFound:单表继承机制 未能找到子类:'clean_slate'。引发此错误 因为“story_type”列是为存储类而保留的 继承的情况。如果您不打算这样做,请重命名此列 用于存储继承类或覆盖 Story.inheritance_column 为该信息使用另一列。

是否有通过 ActiveRecord 直接执行此操作的方法,或者我是否需要使用临时列、SQL 等?

【问题讨论】:

  • 所以你已经有一个 story_type 列,其中包含类名的下划线版本(即'clean_slate'),现在你想将它移动到 STI,使用 story_type 作为 STI 列,并将story_type 值转换为类名?你目前有多少个story_type 值?
  • @muistooshort 没错。我目前有两个 story_type 值。

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


【解决方案1】:

在迁移中使用模型通常不是一个好主意,因为模型类假设它们知道数据库结构是什么,但迁移旨在操纵数据库结构。您的错误消息只是模型类与数据库不同步的一种情况。只要Story.all 尝试实例化模型,您就会得到ActiveRecord::SubclassNotFound STI 异常,因为ActiveRecord 期望在story_type 中找到类名,但您仍然在story_type 中有旧的字符串类型:您无法修复你的数据库使用模型,直到你的数据库被修复。

我建议您假装您的模型在迁移中根本不存在,如果您直接使用数据库,您将会有更好的时间。您只有两个 story_type 值,因此 SQL 非常简单:

def up
  connection.execute(%q{
    update stories
    set story_type = case story_type
      when 'whatever1' then 'Whatever1Story'
      when 'whatever2' then 'Whatever2Story'
    end
  })
end

只有两个值,你知道它们是什么,所以不要浪费时间试图变得聪明。

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2016-10-08
    • 2021-10-30
    • 2011-06-29
    相关资源
    最近更新 更多