【发布时间】:2018-02-08 12:25:21
【问题描述】:
我做了大量工作来重构大量代码,并对 db 架构进行了重大更改。现在我正在尝试编写一个 rake 任务来将记录从旧表迁移到新表。
我正在上这样的课:
#app/models/restream/service.rb
class Restream::Service < ActiveRecord::Base
def self.types
%w(custom multiple_destinations_service one_destination_service) +
Restream::Custom.types + Restream::MultipleDestinationsService.types
end
def self.find_sti_class(type_name) #allows to find classes by short names
type_name = "Restream::#{type_name.camelcase}".constantize
super
end
end
#app/models/restream/custom.rb
class Restream::Custom < Restream::Service
def self.sti_name
"custom"
end
def self.types
%w(periscope odnoklassniki vkontakte)
end
end
#app/models/restream/periscope.rb
class Restream::Periscope < Restream::Custom
def self.sti_name
"periscope"
end
end
一切正常。直到我尝试手动添加记录。 在我以前的版本中,我有这样的结构:
class Restream::Custom < ActiveRecord::Base
def self.types; %w(custom periscope vkontakte); end
end
class Restream::Periscope < Restream::Custom
def self.sti_name; 'periscope'; end
end
现在我尝试从旧的restream_custom 表中获取所有记录,然后复制类型。大致:
Restream::Custom.create(type: old_restream_custom.type)
那失败了:
ActiveRecord::SubclassNotFound: Invalid single-table inheritance type: periscope is not a subclass of Restream::Custom
显然不是!但无论如何,我已经有一堆type: 'periscope' 的记录,所以我知道这是一个有效值。
这是什么原因,我该如何解决这个问题?
======
我可以看到两种方式:
1) 将type 设置为Restream::Periscope,而不仅仅是periscope。但这会创建记录,Restream::Periscope.find_each 或 Restream::Custom.find_each 或类似的东西找不到,因为它会在其 type 列中搜索带有 periscope 的记录,而不是 Restream::Periscope。
2) 从restream_custom 表中仅选择custom、periscope 等每种类型的记录,并为潜望镜创建Restream::Periscope,而不是Restream::Custom,并尝试在此处提供正确的类型。但我发现它有点不漂亮、不干燥且没有必要,我想知道我是否可以用它做得更漂亮。
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 activerecord rake rake-task