如何始终使用基类并忽略Rails中的STI?

时间:2012-02-11 17:52:58

标签: ruby-on-rails sti

我有一个模块,我已经在几个模型中包含了这个内容:

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")

我不喜欢这两种解决方案。还有更好的吗?

2 个答案:

答案 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