10

我有一个模块,我将其包含在几个具有此内容的模型中:

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

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

4

2 回答 2

27

首先,您始终可以使用方法 base_class 访问基类:

self.class.base_class.find_by_foo(bar)

但是,在上面的示例中,您不必访问基类。您只需执行以下操作,Rails 就会知道正确的表名:

self.class.where(:foo => bar)

实际上很少有需要访问基类的情况。

于 2012-10-16T20:16:29.053 回答
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
于 2012-02-11T18:37:10.230 回答