3

I have a user, membership and group model. A user has many memberships, and groups through memberships. A group has many memberships, and users through memberships. Memberships belongs to both.

When a user accesses the users index view I want to show him/her all users that belong to the group he/she belongs to: I created the following code, which does not work. I cannot seem to get the query to work. Pease help!

The code in the Users controller

class UsersController < ApplicationController

  def index
      @users = current_user.relevant_members
  end

end

The code in the User model

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

I don't understand why, when tested in the console, user_ids is not an array of ids, but the following array:

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

What would be a better way of returning an array of user ids to find all relevant group members?

5 Answers 5

4

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

returns always an array of Membership objects, select("user_id") changes only the fields that are loaded from DB to the object.

It's enough to map it to id

user_ids = Membership.select("user_id").where("group_id IN (#{group_ids.join(", ")})").map(&:user_id)
Sign up to request clarification or add additional context in comments.

Comments

2

Membership.select('user_id') will return an array of Membership objects with just the user_id attribute, that's correct so far. It will work if you extract the ids from the result:

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

Best regards

Tobias

Comments

2

Did you try the pluck() function ? https://apidock.com/rails/ActiveRecord/Calculations/pluck

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

Comments

1

This is because your user_ids is an object of the class Membership and hence you can't get an array of the 'user_ids' directly

You have to do something like following

  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)

Also you can modify your where clause as follow, which is more ruby way.

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.