This is a project, where a user has a list a friends, and each friend has their list of friends. What I want is a list of common friends between the "selected user" and each of his "friends", without abusing "each do" loops.
selected_user = User.all.find_by_username("Juan")
data = selected_user.friends.map do |friend|
friend.friends.select do |friend_from_friend|
friend_from_friend.id != selected_user.id
end
end
render json: data ,include: [:friends]
## good piece of data, but Im looking for common friends
## the select is not filtering "Juan" as it should ?
[
{
"id": 2,
"username": "Matt",
"friends": [
{
"id": 1,
"username": "Juan", <== current_user ( or Juan ) should not be returned
},
{
"id": 3,
"username": "Bill",
},
{
"id": 4,
"username": "Sophia", <== Is not one of current_user ( or Juan ) friends.
}
]
},
{
"id": 3,
"username": "Bill",
"friends": [
{
"id": 1,
"username": "Juan", <== current_user ( or Juan ) should not be returned
},
{
"id": 2,
"username": "Matt",
},
{
"id": 4,
"username": "Sophia", <== Is not one of current_user ( or Juan ) friends.
}
]
},
]
What I'm looking for a list very similar to this one, with only common friends to Juan.
The first map seems good to me, it's exactly the chunk of data i'm looking for but then, if only I could remove the entries I dont like.
I think it's more on the 2nd loop where I lose it. Tried with select, filter, find, map, maybe I could share my sql associations.
I dont know, just correct me if you see anything wrong Im doing. Thanks.
#################### EDIT #######################
I solved my problem without touching my associations, I'm really happy I went from 7-15 seconds loading time for a 4k lines json file, to only 0.2 seconds.
## GET USER FRIENDS INCLUDES COMMON FRIENDS
selected_user = User.find_by_username(params[:username])
data = []
selected_user_list_of_friends_ids = selected_user.friends.map {|el|el.id}
current_user_list_of_friends_ids = current_user.friends.map {|el|el.id}
selected_user.friends.map do |friend|
guy = {owner_id: friend.id, owner_username: friend.username, owner_avatar_link: friend.avatar_link}
res = friend.friends.filter do |el|
el.id != current_user.id && selected_user_list_of_friends_ids.exclude?(el.id)
end
if current_user_list_of_friends_ids.include?(friend.id)
guy[:users] = res
else
guy[:users] = []
end
data.push(guy)
end
render json: data