我有一个模块,我已经在几个模型中包含了这个内容:
self.class.find_by_foo(bar)
在我开始使用STI之前一切都很好。该行应始终生成查询
select * from table where foo=bar"
和不
select * from table where foo=bar AND type="Whatever"
有一种简单的方法可以避免它吗?
我虽然有两个解决方案。走向类层次结构,直到找到ActiveRecord::Base
之前的最顶级类或手动运行查询,如:
self.class.find_by_sql("select * from #{self.class.table_name} where foo=bar")
我不喜欢这两种解决方案。还有更好的吗?
答案 0 :(得分:23)
首先,您始终可以使用方法base_class:
访问基类self.class.base_class.find_by_foo(bar)
但是,在上面的示例中,您不必访问基类。您可以执行以下操作,Rails将知道正确的表名:
self.class.where(:foo => bar)
当您需要访问基类时,实际上很少有这种情况。
答案 1 :(得分:2)
在有更好的答案之前,我正在使用此代码来查找STI链的基类:
klass = self.class
self.class.ancestors.each do |k|
if k == ActiveRecord::Base
break # we reached the bottom of this barrel
end
if k.is_a? Class
klass = k
end
end