ActiveRecord自定义类型命名方案
我正在处理一个已经有一个自然类型名称列的表。 例如,已经存在一个名为'provider'的列,其值为'foo'或'bar'。 我想使用现有的类型名称在这张表上使用STI,因为似乎很难为Active Record添加一个名为'type'的列。 问题是,这些类型名称与Ruby类完全不匹配。 我希望能够建立一个自定义的映射,例如Class1 => foo,Class2 => bar。
我尝试了以下内容:
# In the base class
set_inheritance_column :provider
# In Class1
def self.sti_name
'foo'
end
# In Class2
def self.sti_name
'bar'
end
但是这似乎并没有削减它,我得到:
The single-table inheritance mechanism failed to locate the subclass: 'foo'
...
activerecord (3.0.8) lib/active_record/base.rb:923:in `find_sti_class'
它看起来像ActiveRecord只能处理完整的类名和解调类名。 我不确定具有受保护的sti_name方法的目的是什么。
我将深入挖掘框架并重写ActiveRecord :: Base.compute_type。 在我这样做之前,有没有人做过? 这是一个疯狂的追逐?
钢轨可以处理自定义类型名称,还是坚持使用Ruby类名?
更新
我得到了这个工作:
# In the base class
def self.find_sti_class(type_name)
# Do mapping from foo/bar to Class1/Class2
...
end
我仍然警惕在道路上遇到更多问题。 这是正确的方法吗?
我有类似的情况,并找到了这个链接的解决方案:https://gist.github.com/1381880
看看AR代码,只关注sti_name
并instantiate
它,似乎它可能足以让你修补这两种方法。
我没有这方面的经验,但看起来并不复杂。 下面是instantiate
样子:
def instantiate(record)
model = find_sti_class(record[inheritance_column]).allocate
model.init_with('attributes' => record)
model
end
理想情况下,您希望扫描代码以查找引用类似record[inheritance_column]
东西或只是简单的inheritance_column
并在其中注入您自己的映射代码。 只是一个快速的看,它似乎没有在那么多地方使用。
我会说你正在尝试的是可能的:),但是你将需要基本实例的测试用例+涉及到关联的东西,以确保AR可以为不同情况找到并构建正确的SQL。
很明显,尽管AR并没有用你想要的内容来构建,因为在代码中使用inheritance_column
并不是清楚地被抽象到任何地方。 所以这就是为什么你需要在代码中多探究一下。