1

Just wanted an opinion on this in terms of design and efficiency.

Let's say you have a social network for liking music.

If you have query like music.users and out of those users you want to identify your friends. Visually you want to add a feature to identify these friends, maybe all your friends have a star on their profile and non friends are left alone.

Is it really inefficient/expensive to be checking each user to see if they are a friend? Alternate methods?

Clam
  • 935
  • 1
  • 12
  • 24

1 Answers1

0
result = music.users(:user)
              .optional(:friends, :friend)
              .where(neo_id: current_user.neo_id)
              .pluck(:user, is_friend: 'friend IS NOT NULL')

This would return an array of tuples: Each user from the association, and a boolean stating if they are friends of the current user

The .optional(:friends, :friend) is like calling .friends(:friend), but is uses an OPTIONAL MATCH instead of a MATCH in cypher for querying the association.

For the is_friend part, that translates to RETURN friend IS NOT NULL AS is_friend. Actually, since this is a pluck, the AS isn't necessary, so it could just be .pluck(:user, 'friend IS NOT NULL'). Since it's doing an OPTIONAL MATCH, the friend variable in the query (which is the current_user) will only be there if the user from the result row is friends with the current_user.

One thing that you can do to help with understanding of what the query chain would do is to call to_cypher to see what query would be generated. In this case, that would be:

puts music.users(:user)
          .optional(:friends, :friend)
          .where(neo_id: current_user.neo_id)
          .return(:user, is_friend: 'friend IS NOT NULL')
          .to_cypher

The pluck is a method that returns an array instead of a query chain object, so I replaced it with return in this case.

Brian Underwood
  • 10,746
  • 1
  • 22
  • 34
  • Also, this could be accomplished a bit better if we had eager loading, which is something that we want to implement soon – Brian Underwood Mar 09 '15 at 11:22
  • If you retrieve that user's friends, I can handle the logic in the view?. Because I'm thinking you will need to loop through each user, and do a check like `includes?` for every user against yourself, if true, then you can show the star. – Clam Mar 09 '15 at 20:50
  • Can you explain the query a bit. What does the optional `friend` do? I think I get the optional `friends` as we're seeing if that's a match. And what would `is_friend` be? – Clam Mar 10 '15 at 02:52