2

Rails3には次のものがあります:

Class Teacher
  #  active                 :boolean
  has_and_belongs_to_many :subjects

Class Subject
  #  active                 :boolean
  has_and_belongs_to_many :teachers

に関連付けられている、または関連付けられてTeachersいるすべてを返す Teacher スコープを作成しようとしています。activeSubjectactive

これらのスコープは個別に機能しますが、OR を使用して単一のスコープとして組み合わせるにはどうすればよいでしょうか?

scope :active_teachers, where(active: true)
scope :more_active_teachers, joins(:subjects).where(:subjects => {active: true})

私は成功せずにこれを試しました:

scope :active_teachers, where(active: true).or(joins(:subjects)
      .where(:subjects => {active: true}))

アップデート:

解決策があると思っていたのですが、これはもはや遅延読み込みではなく、データベースに 2 回ヒットし、最も重要なことに、AR オブジェクトではなく配列を返します!

scope :active_teachers, where(active: true) |
                        joins(:subjects).where(:subjects => {active: true})
4

4 に答える 4

5

あなたはSqueelあなたの救助をしなければなりません。詳細はこちら

それを使用して、次のようなものを定義できます。

class Teacher
  ...
  scope :active_teachers, joins{subjects}.where {(active == true) | (subjects.active == true)}
  ...
end
于 2013-05-12T11:14:54.367 に答える
3

これは AREL にドロップすることで解決できます。その方法については、この SO の質問を参照してください。

AREL OR 条件

またはAREL ソースコード README.mdから。特定の例では、これは次のように変換されると思います(ただし、確認していません)。

teachers.where(teachers[:active].eq(true).or(subjects[:active].eq(true)))

幸運を!

于 2013-05-15T15:43:41.737 に答える
3

簡単に言えば、できないと思います。

コード内で oring を実行すると、遅延読み込みが中断されます...評価を行うにはデータベースが必要なため、実際にはそれを回避する方法はありません。ActiveRecord は、各節を個別に実行しないと、スコープで評価を行うことができません。

このようなものは、次のように機能するはずです。

joins(:subjects).where("subjects.active = true OR teachers.active = true")

それほどエレガントではありませんが、再利用のためにメソッドにラップできます。

于 2013-05-12T11:36:14.683 に答える
1

このための Rails プル リクエスト ( https://github.com/rails/rails/pull/9052 ) がありますが、それまでの間、イニシャライザに含めることができるモンキー パッチを作成した人がいます。これとまだあなたに与えるActiveRecord::Relation

https://gist.github.com/j-mcnally/250eaaceef234dd8971b

これにより、このようにスコープをORすることができます

Teacher.active_teachers.or.more_active_teachers

または新しいスコープを書く

scope :combined_scopes, active_teachers.or.more_active_teachers
于 2013-05-15T16:58:07.807 に答える