2011-04-18 100 views
0

我需要通過兩種方式訪問​​機構。 我的模型如下:以兩種不同的方式訪問has_many關係ActiveRecord Rails

class Person < ActiveRecord::Base 
    has_many :institution_people 
    has_many :institution_choices 
    has_many :institutions, :through => :institution_people 
    has_many :institutions, :through => :institution_choices 
    fields........ 
end 

class Institution < ActiveRecord::Base 
    has_many :people, :through => :institution_people 
    has_many :people, :through => :institution_choices 
    has_many :institution_people 
    has_many :institution_choices 
end 

class InstitutionChoice < ActiveRecord::Base 
    belongs_to :person 
    belongs_to :institution 
end 

class InstitutionPerson < ActiveRecord::Base 
    belongs_to :person 
    belongs_to :institution 
end 

的我的設置是這樣的模式是,人可以在不同的機構學習,所以爲了這個,我設置

has_many :institutions, :through => :institution_people 

的人模型

但在同一時間人可以有機構選擇,所以我設置

has_many :institutions, :through => :institution_choices 

爲人模型。

我應該如何建立人與機構之間的模型和聯繫,以便我可以從兩種方式找到人的機構。

眼下

Person.first.institutions 

從institution_people表認爲,正如

has_many :institutions, :through => :institution_people 

是在開始的時候我猜。

歡迎其他一些技術,以便我可以在兩種方式獲得機構。

回答

1

在你Person模型,試試這個:

class Person < ActiveRecord::Base 
    has_many :institution_people 
    has_many :institution_choices 
    has_many :institutions_people, :through => :institution_people, :source => :institutions, :class_name => "Institution" 
    has_many :institutions_choices, :through => :institution_choices, :source => :institutions, :class_name => "Institution" 
end 

http://guides.rubyonrails.org/association_basics.html#has_many-association-reference

+0

這似乎是一個不錯的解決方案。我一定會嘗試。 – Gagan 2011-04-19 05:19:27

+0

然後投票或接受ಠ_ಠ – 2011-04-20 09:10:04

0

基本上,你需要某種接口在這裏。我會做什麼:

在機構模型:

scope :institutions_of, proc { |person| joins(' INNER JOIN (' + Person.institution_ids(person) + ') q 
    ON institutions.id = q.ip_iid OR institutions.id = q.ic_iid').where(['institutions.person_id = ?', person_id] 

(它加入從下面Person.rb查詢(範圍))

在Person.rb

scope :institution_ids, proc { |person| select('ip.institution_id ip_idd, ic.institution_id ic_idd 
from institution_people ip 
inner join institution_choice ic on ip.person_id = ic.person_id'). 
where(['ip.person_id = ?', person.id]) 

(這應該從兩個表中檢索所有機構ID)

醜陋地獄,但仍然可能工作。你可以使用然後像:Institution.institutions_of(current_user)

0

如果您不需要保持結果作爲ActiveRelation

class Person < ActiveRecord::Base 
    has_many :institution_people 
    has_many :institution_choices 

    def institutions 
    institution_people + institution_choices 
    end 
end 

如果您確實需要保持它(爲了調用person.institutions.order( 'name'),那麼它更復雜:

class Person < ActiveRecord::Base 
    has_many :institution_people 
    has_many :institution_choices 

    scope :institutions, :select => 'select * from (select * from institution_people union all select * from institution_choices) as institutions' 
end 
+0

這是在這兩種情況下的額外查詢。我一直在努力避免這種情況。不知道什麼可能會表現出更好的表現:) – 2011-04-18 13:01:57

+0

試試我的答案,這是最好的方式。 – 2011-04-18 18:17:00

相關問題