5

STIパターンを使用してクラス階層を実装します

class A
  scope :aaa, where([someField]:[someValue])
end

class B < A
end

問題は、私が次のようなものを呼び出そうとすると、次のようになることです。

B.limit(5).aaa
=> SELECT "[table]".* FROM "[table]" WHERE "[table]"."type" IN ('A') AND ([someField] = [someValue]) LIMIT 5

したがって、スコープ:aaaを満たすタイプAの5つのオブジェクトを取得していますが、タイプ="B"の行でも同じことを行う必要があります。

STIパターンの子でスコープを再定義せずに、親からスコープを使用する方法はありますか?

前もって感謝します

編集済み

私はちょうど私の友人とそれについて話し合った、そして彼は私に一つの重要なことを見せてくれた。STIのルートクラスではありません。実際、階層全体は次のようになります

class O < ActiveRecord::Base
end

class A < O
  scope ..... .....
end

class B < A
end

多分理由は階層自体にありますか?...

4

3 に答える 3

2

これはマルチレベル階層の結果であるというのは正しいです。

A継承のレベルが1つしかない場合(つまり、から継承するのではActiveRecord::Baseなくから継承する場合) 、スコープは期待どおりに機能しますO

RailsのSTIは、中間クラスを作成すると、常に期待どおりに機能するとは限りません。

これがRailsのバグなのか、それとも何をすべきかを正確に推測できない結果なのかはわかりません。私はそれをもっと研究しなければならないでしょう。

発生したスコープの問題は、予期しない動作の一例にすぎません。もう1つの例は、中間クラスをクエリすると、認識しているクラスタイプのみがクエリされるため、特に必要な場合を除いて、すべてのサブクラスが含まれるとは限りません。

詳細については、次のスレッドを参照してください。特に、MatthewRudyによる下部の投稿:https ://groups.google.com/forum/#!topic / hkror / iCg3kxXkxnA

@Atastorによって提案されているように、クラスメソッドの代わりにスコープを使用したい場合は、のO代わりにスコープを設定できますA。スコープがのすべてのサブクラスに適用できるとは限らないため、これは理想的ではありませんがO、Railsがtype列内の正しいクラスを照会するように思われ、簡単な回避策です。

于 2012-10-20T16:33:45.070 に答える
1

スコープの代わりにクラスメソッドを使用するように切り替えます(例:クラスA)

def self.aaa
  A.where([someField]:[someValue])
end 

その後、クラスBで

def self.bbb
  self.aaa.where("type = ?","B")
end
于 2012-09-17T15:36:50.727 に答える
0

STI中間クラスは、試行しているスコープを混乱させる可能性があるため、注意してください。

私の場合、私は次のことをしました。

class A < ActiveRecord
blabla
end
class B < A
scope :dates, ->(start_date, end_date) { where(:date => start_date..end_date) }
end
class C < B
<call scope_dates>
end
class D < B
<call scope_dates>
end

そして、スコープには実際にはクラスCとクラスDの組み合わせが含まれていました。

したがって、RailsにSTIがある場合は、スコープを中間クラスではなく基本クラスに配置してください

于 2015-02-18T15:17:06.710 に答える