2015-04-17 45 views
0

在我的應用程序(Rails 4.2.0.rc2)中,用戶可以是學生或特定機構的管理員。 User上有一個關聯:admin_institutions,它通過檢查連接表中的role返回用戶是管理員的所有機構。 Institution上還有一個關聯:students,該關聯返回所有在該機構的學生的用戶,同樣根據institution_users.role在Has_many中,ActiveRecord關聯中的條件彼此衝突?

這些協會按預期工作,所以我添加了一個協會:admin_studentsUser,意思是返回給定用戶是管理員的所有機構的所有學生。

class InstitutionUser < ActiveRecord::Base 
    belongs_to :institution 
    belongs_to :user 
end 

class Institution < ActiveRecord::Base 
    has_many :institution_users 
    has_many :users, :through => :institution_users 
    has_many :students, -> { where "institution_users.role = 'Student'" }, :through => :institution_users, source: :user 
    ... 
end 

class User < ActiveRecord::Base 
    has_many :institution_users 
    has_many :admin_institutions, -> { where "institution_users.role = 'Admin'" }, through: :institution_users, source: :institution 
    has_many :admin_students, through: :admin_institutions, source: :students 
    ... 
end 

但是,:admin_students不能正常工作。它生成以下SQL:

選擇 「用戶」 * FROM 「用戶」 INNER JOIN 「institution_users」 ON 「用戶」, 「ID」= 「institution_users」 「user_ID的」 INNER JOIN 「機構」 ON「。院校用戶「,」院校用戶「,」院校用戶「,」院校用戶「,」院校用戶名「,」院校用戶「,」院校用戶「,」院校用戶「,」院校用戶「 institution_users.role =「學生」)和(institution_users.role =「管理員」)[「user_ID的」,190]

而不是尋找所有機構,其中用戶是管理員,選擇他們所有的螺柱ents,它似乎在尋找用戶既是學生又是管理員的機構,因此它會返回一個空集合。

有沒有辦法寫一個關聯(而不僅僅是一個方法),它會給我我想要的結果,而不會像我這樣有條件衝突?

(旁註:?難道這對於這種關聯的預期行爲如果是這樣,我會很感激進一步瞭解爲什麼ActiveRecord的解釋是它的方式)

回答

1

這可能不是答案,但也許會導致一個。

我不是硬編碼SQL協會的粉絲:

-> { where "institution_users.role = 'Student'" } 

他們肯定是問題,至少部分是因爲他們無法通過ActiveRecord的解釋,以確定institution_users的表別名應用於。

您可以允許ActiveRecord的靈活性通過引用InsitutionUser模型的類方法:

def self.students 
    where(role: "Student") 
end 

這也保持了InstitutionUser邏輯在同一個地方。

然後關聯變爲:

has_many :students, -> {merge(InstitutionUser.students)}, :through => :institution_users, source: :user 

也許這種嘗試一下,看看是否排序,爲你,如果沒有它可能得到的東西在正確的方向前進。

+0

謝謝!我嘗試將它改爲像'where institution_users:{role:'Student'}'的語法,但得到了相同的結果。然後嘗試您的建議,但它會生成相同的查詢,這次是以作爲參數傳遞的角色。我會一直捅它... – molgin