Rails子类化和STI

时间:2012-09-06 14:39:13

标签: ruby-on-rails activerecord inheritance sti

我正在开发一个Rails项目OldApp,它正在使用STI来创建一些类Foo。 目前,我们正在进行大量的增量重写。为了缓解疼痛,我们选择了一种非常规的方法。新的命名空间应用程序NewApp现在仍然是OldApp中的引擎。

我们将在NewApp中创建的模型已在NewApp中创建,OldApp现在将这些模型用作其父类。为什么?现在我们可以将OldApp模型中的代码移动并重构为新模型,OldApp仍然有效,来自OldApp的测试确保NewApp中的重构不会中断东西和OldApp基本上作为待办事项列表(如果OldApp的所有内容都消失了,我们就完成了)。但是; - )

问题是,STI目前有点杀死这个(当时令人惊讶的很好的工作)方法。

   class OldApp::Foo < NewApp::Foo; end
   class NewApp::Foo < ActiveRecord::Base; end

   # in the console
   OldApp::Foo.count #=> SELECT COUNT(*) FROM `foos` WHERE `foos`.`type` IN ('Foo')
   NewApp::Foo.count #=> SELECT COUNT(*) FROM `foos`

当然,OldApp::Foo会这样做,因为它假设它只是NewApp::Foo的STIish子类而不是 Foo NewAppWhatever::Foo }。完全禁用Foo的STI也不起作用,因为实际上我们 使用STI进行NewApp::Foo

我基本上在寻找能够告诉{{1}}它是STI链的基类的东西。

这有意义吗?有点难以解释......

1 个答案:

答案 0 :(得分:1)

使用抽象基类并从中继承OldApp::FooNewApp::Foo就可以了:

class NewApp::FooBase < ActiveRecord::Base
    self.abstract_class = true
end

class NewApp::Foo < NewApp::FooBase; end
class OldApp::Foo < NewApp::FooBase; end

您可以将所有重构的代码放在基类中,以便OldApp::FooNewApp::Foo充当STI的起点。