2011-04-08 121 views
3

我有3種型號:用戶,團隊和成員 -軌複雜許多一對多查詢

class Team < ActiveRecord::Base 
    has_many :memberships 
    has_many :members, :through => :memberships, :source => :user 
end 

class User < ActiveRecord::Base 
    has_many :memberships, :dependent => :destroy 
    has_many :teams, :through => :memberships 

    def team_mates 
    teams = Team.where(:members => id) 
    team_mates = teams.members 
    end 
end 

class Membership < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :team 

    validates :user_id, :presence => true 
    validates :team_id, :presence => true 
end 

而且,我不能完全弄清楚如何寫team_mates方法在用戶模型。它應該返回一組使用current_user的團隊中的其他用戶的數組。我的想法是,我應該使用一個範圍來限制團隊,只包括當前用戶是其成員的團隊,但我無法弄清楚語法。任何幫助,將不勝感激。

謝謝!

回答

5

使用成員資格表查找與您正在調用方法的用戶共享任何團隊的用戶。然後過濾掉與當前用戶共享多個團隊的重複用戶,請使用不同的用戶。

我沒有測試過下面的代碼,但希望這將讓你在正確的道路上:

def team_mates 
    m = Membership.scoped.table 
    Users.join(m).where(m[:team_id].in(team_ids)).project('distinct users.*') 
end 

UPDATE

看起來像一些在這個問題的答案不要」的阿雷爾方法無法輕鬆映射回ActiveRecord的土地。 (如果有人知道如何,我很想知道!)並且它還返回'當前用戶'。試試這個:

def team_mates 
    User.joins(:memberships).where('memberships.team_id' => team_ids).where(['users.id != ?', self.id]).select('distinct users.*') 
end 
+0

謝謝!看起來我們正在接近解決方案。爲了讓連接工作,我必須將用戶作爲一個socoped.table。但是,現在該函數正在返回一個Arel :: SelectManager而不是一組用戶。任何想法如何從Arel :: SelectManager中提取用戶數組?這裏是我的代碼(對不起,格式糟糕): 'def team_mates m = Membership.scoped.table u = User.scoped.table u.join(m).where(m [:team_id] .in(team_ids ))。項目('distinct users。*') 結束' – spinlock 2011-04-08 16:32:48

+0

我在網上搜尋如何將其轉換回ActiveRecord關係對象,這是你想要的。你可以看看最後一條語句的結果,然後執行'.to_sql',然後將它傳遞給'User.find_by_sql':'def team_mates; m = Membership.scoped.table; u = User.scoped.table; sql = u.join(m).where(m [:team_id] .in(team_ids))。project('distinct users。*')。to_sql; User.find_by_sql(SQL);結束' – ctcherry 2011-04-08 17:01:13

+0

檢查此答案的更新。 – ctcherry 2011-04-08 17:13:25

3

怎麼樣?

User.joins(:memberships).joins(:teams).where("teams.id" => id).uniq