rails复杂的多对多查询

时间:2011-04-08 05:19:54

标签: ruby-on-rails-3 scope many-to-many

我有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

而且,我无法弄清楚如何在User模型中编写team_mates方法。它应该使用current_user返回团队中其他用户的数组。我的想法是我应该使用一个范围来限制团队只包括当前用户所属的团队,但我无法弄清楚语法。对此的任何帮助将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分:5)

使用成员资格表查找与您正在调用该方法的用户共享任何团队的用户。然后,要筛选出与当前用户共享多个团队的重复用户,请使用distinct。

我没有测试下面的代码,但希望它会让你走上正确的道路:

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

<强>更新

看起来该答案中的一些Arel方法没有轻松映射回ActiveRecord域。 (如果有人知道如何,我很想知道!)并且它还会返回“当前用户”。试试这个:

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

答案 1 :(得分:3)

怎么样?

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

答案 2 :(得分:0)

也许是这样的

scope team_mates, lambda {|user_id, teams| joins(:memberships).where(:team_id => teams, :user_id => user_id)}

def team_mates
  User.team_mates(self.id, self.teams.collect {|t| t.id})
end

以下是更多信息:

http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html