11

組織のモデル(ネストされたセット)があります。私は人々のモデルを持っています。人は別の人を代理人にすることができます。組織は個人によって所有されます。組織は、所有者またはその代理人にのみ表示されます。

特定の人が表示できるすべての組織を取得したいと思います。その人が所有する、または特定の人が代理人である人が所有するすべての組織:

o = Arel::Table.new(:organisations)
p = Arel::Table.new(:people)
pd = p.where(p[:id].eq(3).or(p[:deputy_id].eq(3))).project(:id)
op = o.join(p).where(o[:person_id].in(pd)).project("distinct organisations.*)

最後の結合を定式化するためのより良い方法があるかもしれませんが、個人とその代理人のクエリを、個人とその代理人に表示される組織のクエリから分割したいと思います。

最後の結合は Arel::SelectManager を返します (これに関する有用なドキュメントはどこにもないようです)。

SelectManager を ActiveRecord::Relation に変換して、「構成中の閉鎖」の概念全体から利益を得る方法はありますか?

組織に関する上記のクエリに再度参加して、個人またはその代理人に表示される組織のすべての子孫を取得するにはどうすればよいですか? 私は SQL を知っていますが、常に SelectManager で組織の自己結合に失敗します。

4

3 に答える 3

8

答えを求める人はいないようで、私は自分で解決策を見つけました:

1. 最後の結合をActiveRecord::Relation

Organisation.where(o[:id].in(op))

Arel::SelectManager.to_aこれに関する唯一の問題は、非推奨の警告が表示される this 呼び出しです (また、コストのかかる操作でもあります)。ただし、代替手段は見つかりませんでした (何もないと思われます。この非推奨の警告は、Arel で観察できる矛盾の 1 つにすぎず、ActiveRecord で採用されています)。

2.ネストされたセットで自己結合してすべての子孫を取得する

o = Organisation.scoped.table
op = Organisation.where(o[:person_id].in(Person.self_and_deputies(person_id).project(:id))).arel
o1 = Arel::Table.new(:organisations, :as => "o1")
o2 = Arel::Table.new(:organisations, :as => "o2")
o3 = o1.join(o2).on(
     o1[:lft].gteq(o2[:lft]).and(
     o1[:rgt].lteq(o2[:rgt]))).where(
     o2[:id].in(op)).project("distinct o1.id")
Organisation.where(o[:id].in(o3))
于 2010-12-23T20:26:50.933 に答える
4

に渡すことができるjoin_sourcesのインスタンスを呼び出すことができるはずです。クエリは次のようになります(テストされていません):Arel::SelectManagerActiveRecord::Relation#joins

o = Organisation.scoped.table
op = Organisation.where(o[:person_id].in(Person.self_and_deputies(person_id).project(:id))).arel
o1 = Arel::Table.new(:organisations, :as => "o1")
o2 = Arel::Table.new(:organisations, :as => "o2")
o3 = Organization.joins(
  o1.join(o2).
    on(o1[:lft].gteq(o2[:lft]).and(o1[:rgt].lteq(o2[:rgt]))).join_sources).
  where(o2[:id].in(op)).
  project("distinct o1.id")
于 2013-03-13T05:57:59.903 に答える