Ruby on rails 如何在Rails中始终使用基类并忽略STI?

Ruby on rails 如何在Rails中始终使用基类并忽略STI?,ruby-on-rails,sti,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_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")

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

在找到更好的答案之前,我将使用以下代码查找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

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

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

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

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

在Rails 4
self.class
中意外地返回了对象父类,在Rails 5
self.class
中意外地返回了模型类
self.class.base_class
可用于获取父类。