#ruby-on-rails #ruby #ruby-on-rails-3
#ruby-on-rails #ruby #ruby-on-rails-3
Вопрос:
У меня есть следующие две модели:
Project, has_many ProjectParticipants
ProjectParticipants, belongs_to Project
Как я могу запросить определение, учитывая эти 5 участников проекта, принадлежат ли они проекту?
Кроме того, это должны быть строго эти 5, не больше и не меньше.
Есть мысли о том, как элегантно решить для этого типа подсчета?
Ответ №1:
Предполагая, что participants
содержит 5 участников, которых вы хотите проверить.
participants.all? {|o| o.project }
Это вернет значение true для всех участников проекта, в противном случае false.
Чтобы вернуть найденный проект, вы можете сделать:
И посмотреть, все ли участники имеют один и тот же проект:
first_participant = participants.shift
participants.all? {|o| o.project == first_participant.project} unless first_participant.nil?
Преимущество этого метода в том, что он замыкается, если у одного из участников нет такого же проекта (более эффективный).
Редактировать:
Чтобы вернуть проект, который они все совместно используют, вы можете сделать:
first_participant = participants.shift
project_shared = participants.all? {|o| o.project == first_participant.project} and first_particpant.project unless first_participant.nil?
для project_shared будет установлен проект, к которому они все совместно используют, в противном случае он будет равен нулю / false.
Таким образом, вы можете затем сделать:
if project_shared
# do work
else
# they dont share a project!
end
Комментарии:
1. Майк, в этом проблема, у меня нет проекта. Учитывая участников, я хочу определить, существует ли проект для этих людей или нет?
2. это, это здорово. Если совпадение действительно найдено, есть ли способ вернуть этот проект?
3. Спасибо за это, Майк, я только что попробовал это и получаю NoMethodError (неопределенный метод `project.’ для #<Пользователь: 0x10fa4de30>):
Ответ №2:
Вы можете сравнить свойства записей, участвующих в проекте, в группе:
participants.length == 5 and participants.all? { |p| p.project_id == project.id }
Это подтверждает, что ваш массив участников содержит пять записей и что всем им присвоен один и тот же project_id. Сравнение p.project == project
будет иметь побочный эффект загрузки одного и того же проекта пять раз.
Чтобы проверить, принадлежат ли они просто проекту, вы можете сделать это:
participants.length == 5 and participants.all? { |p| p.project_id? }
Этот проект может быть удален, а ссылка может быть недействительной, поэтому вам, возможно, придется прибегнуть к фактическому извлечению его:
participants.length == 5 and participants.all? { |p| p.project }
Вы также можете использовать group_by
метод, чтобы увидеть, задействован ли только один проект:
grouped = participants.group_by(amp;:project)
!grouped[nil] and grouped.length == 1 and grouped.first[1].length == 5
group_by
Метод организует данный массив в хэш, где ключ указан в качестве параметра, а значение представляет собой список совпадающих объектов. Это может быть удобно в подобных ситуациях.
Комментарии:
1. спасибо, но я не уверен, что это сработает. Учитывая 5 человек и ничего не зная о проекте. Я хочу определить, принадлежат ли эти 5 человек уже существующему проекту в БД. Мысли?
2. Я добавил обновление. Ваш вопрос был не очень ясен в деталях.