рельсы сложный запрос многие ко многим - PullRequest
3 голосов
/ 08 апреля 2011

У меня есть 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.Я думаю, что я должен использовать область действия, чтобы ограничить команду только теми командами, в которых текущий пользователь является участником, но я не могу понять синтаксис.Любая помощь по этому вопросу будет принята с благодарностью.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 08 апреля 2011

Используйте таблицу членства, чтобы найти пользователей, которые разделяют любую команду с пользователем, для которого вы вызываете метод.Затем, чтобы отфильтровать дублирующих пользователей, которые совместно используют более 1 команды с текущим пользователем, используйте отличные.

Я не тестировал приведенный ниже код, но, надеюсь, он выведет вас на правильный путь:

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
3 голосов
/ 11 июня 2012

Как насчет?

User.joins(:memberships).joins(:teams).where("teams.id" => id).uniq
0 голосов
/ 08 апреля 2011

Может быть, что-то вроде этого

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...