2012-02-11 12 views
5

私は、このコンテンツにはいくつかのモデルに含めていますモジュールを持っている:私はSTIの使用を開始するまでRailsで基本クラスを使用してSTIを無視するにはどうすればよいですか?

self.class.find_by_foo(bar) 

すべてが大丈夫でした。その行は、常にそれを回避するための簡単な方法があり、クエリ

select * from table where foo=bar" 

ない

select * from table where foo=bar AND type="Whatever" 

を生成する必要がありますか?

私は2つの解決策のうちですが、私はどちらかのソリューションを好きではない

self.class.find_by_sql("select * from #{self.class.table_name} where foo=bar") 

:私はActiveRecord::Base前に、最上位のクラスを見つけるかのように、手でクエリを実行するまでクラス階層を歩きます。良いものはありますか?

答えて

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 
19

まず、あなたは常にメソッドのBASE_CLASSで基底クラスに取得することができます。

self.class.base_class.find_by_foo(bar) 

ただし、上記の例では、ベースクラスにアクセスする必要はありません。次のようにすれば、Railsは正しいテーブル名を知ることができます。

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

実際には、基本クラスにアクセスする必要があるケースはほとんどありません。

+0

Rails 4 'self.class'では、予期せずオブジェクトの親クラスがRails 5' self.class'に返されましたが、モデルクラスは例外として返されます。 'self.class.base_class'を使って親クラスを取得できます。 – Kris

関連する問題