Найти средний объект во вложенных имеет много

Я установил ассоциацию, в которой мои сущности определены так, что

В проекте много команд, в команде много пользователей

У меня есть объект проекта, и мне нужно найти, к какой команде принадлежит пользователь. Итак, если бы я был в консоли, я хотел бы сделать это:

project = Project.find(5)
project.team_id_for_user_id(7)

Есть ли простой рельсовый способ сделать это или мне нужно перебирать команды проекта, а затем перебирать каждого из пользователей команды, пока я не найду идентификатор пользователя, а затем верну идентификатор команды для текущей команды?

Моя терминология, вероятно, здесь неверна, что, вероятно, является причиной того, что я не смог найти ответ в другом месте.


person Matt Long    schedule 30.03.2014    source источник


Ответы (1)


Это зависит от связи между Team и User. Может ли пользователь принадлежать более чем к одной команде? Если да, то что, если команды связаны с одним и тем же проектом?

Вариант 1, простой:

class Project
  has_many :teams
end

class Team
  belongs_to :project
  has_many :users
end

class User
  belongs_to :team
end

user_id = 7
@team = User.find_by(id: user_id).team

Вариант 2, более сложный:

class Project
  has_many :teams
end

class Team
  belongs_to :project
  has_and_belongs_to_many :users
end

class User
  has_and_belongs_to_many :teams
end


@project = Project.find_by(id: 5)
user_id = 7
@user = User.find_by(id: user_id)
@team = @user.teams.where(project_id: @project.id).first

В последней строке запрос @user.teams.where(project_id: @project.id) вернет одну запись Team, если пользователь является частью одной команды для каждого проекта (необходима специальная проверка).

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

person tompave    schedule 30.03.2014
comment
В порядке. Да. Ваш второй более сложный пример - это то, что я искал. И пользователь может принадлежать только к одной команде и, следовательно, к одному проекту, так что это будет работать отлично. Спасибо! - person Matt Long; 30.03.2014
comment
Пожалуйста. Однако, если, как вы говорите, пользователь может принадлежать только к одной команде и, следовательно, к одному проекту, тогда вам может быть лучше использовать ассоциации, которые я описал в первом примере. - person tompave; 30.03.2014
comment
После вашего первого примера я понял, что это сложнее, чем я выразил в своем вопросе. Я использую модель соединения (has_many, through), которая называется team_membership. Команда принадлежит проекту и имеет много участников через team_memberships. В проекте много команд. У пользователя много команд через team_membership. У пользователя также есть много проектов-участников через команды, исходный проект. У пользователя также есть много проектов, потому что это собственные проекты пользователя, однако это несущественно для той части ассоциации, о которой мы здесь говорим. Несмотря на это, ваш второй пример отлично работает! ;-) - person Matt Long; 30.03.2014