Результаты массива с использованием модели запроса активной записи ‘select’ и ‘where’

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня есть модель пользователя, членства и группы. Пользователь имеет много членств и групп через членство. В группе много участников и пользователей через членство. Членство принадлежит обоим.

Когда пользователь обращается к представлению индекса пользователей, я хочу показать ему / ей всех пользователей, принадлежащих к группе, к которой он принадлежит: я создал следующий код, который не работает. Кажется, я не могу заставить запрос работать. Пожалуйста, помогите!

Код в пользовательском контроллере

 class UsersController < ApplicationController

  def index
      @users = current_user.relevant_members
  end

end
 

Код в пользовательской модели

 def relevant_members
  group_ids = self.group_ids
  user_ids = Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})")
  User.find(user_ids)
end
 

Я не понимаю, почему при тестировании в консоли user_ids представляет собой не массив идентификаторов, а следующий массив:

 [#<Membership user_id: 2>, #<Membership user_id: 2>, #<Membership user_id: 3>, #<Membership user_id: 3>, #<Membership user_id: 3>, #<Membership user_id: 2>]
 

Что было бы лучшим способом возврата массива идентификаторов пользователей для поиска всех соответствующих членов группы?

Ответ №1:

Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})")

всегда возвращает массив объектов членства, select («user_id») изменяет только поля, которые загружаются из базы данных в объект.

Достаточно сопоставить его с id

 user_ids = Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})").map(amp;:user_id)
 

Ответ №2:

Membership.select('user_id') вернет массив Membership объектов только с этим user_id атрибутом, пока это правильно. Это сработает, если вы извлечете идентификаторы из результата:

 membershipts = Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})")
user_ids = memberships.map(amp;:user_id)
 

С наилучшими пожеланиями

Тобиас

Ответ №3:

Вы пробовали функцию pluck () ? https://apidock.com/rails/ActiveRecord/Calculations/pluck

 user_ids = Membership.pluck("user_id").where("group_id IN (#{group_ids.join(", ")})")
 

Ответ №4:

Это связано с тем, что your user_ids является объектом класса Membership и, следовательно, вы не можете получить массив идентификаторов пользователя напрямую

Вы должны сделать что-то вроде следующего

   user_ids = Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})")
  user_ids_array = user_ids.collect{|u| u.user_id}
  User.find(user_ids_array)
 

Также вы можете изменить свое предложение where следующим образом, что является более рубиновым способом.

 user_ids = Membership.select("user_id").where(["group_id IN (?)", group_ids])
 

Ответ №5:

 Membership.where("group_id in (#{groups.collect(amp;:id).join(',')})")
    .all.collect(amp;:user_id)