Je travaille sur une application qui modélise les amitiés entre utilisateurs. Lorsque deux utilisateurs deviennent amis, deux instances de la classe d'amitié sont créées, une pour chaque direction de l'amitié. Cela est nécessaire car des autorisations différentes peuvent être définies dans chaque direction, ainsi que pour faciliter les recherches. Ainsi, nous recherchons toujours par user_id sans créer d'index supplémentaire et en doublant les recherches.Ruby on Rails: Est-il possible de: inclure l'autre jambe d'une table de joint circulaire?
Est-il possible, en utilisant soit find ou une portée nommée pour attirer un ami avec la contre-amitié? Je voudrais le faire parce que je permets aux utilisateurs d'éditer des permissions d'amitié qui sont stockées dans leur propre jambe de l'amitié, et ainsi quand j'indique l'information d'un ami à l'utilisateur je dois vérifier l'autre jambe pour voir comment les autorisations sont définies. (En aparté, cela vous semble-t-il une manière logique de faire les choses? Soit vous stockez dans le côté opposé, soit vous devez consulter le côté opposé avant l'affichage, les deux étant désagréables.)
concocter un lot de SQL qui fait le travail:
def self.secure_friends(user_id)
User.find_by_sql("SELECT u.*, cf.permissions
FROM users u
INNER JOIN friendships f ON u.id = f.friend_id
INNER JOIN friendships cf ON u.id = cf.user_id AND cf.friend_id = #{user_id}
WHERE ((f.user_id = #{user_id}) AND (f.status = #{Friendship::FULL}))")
end
la fonction retourne tous les noms d'amis et ids d'un utilisateur, ainsi que les autorisations. Cependant, cela ne semble pas idéal et signifie que je dois accéder aux permissions en appelant friend.permissions, où les permissions ne sont pas réellement un membre d'un ami mais sont juste fusionnées en tant qu'attribut par find_by_sql. Dans l'ensemble, je préfèrerais le faire avec un named_scope ou un appel find, mais malheureusement, chaque tentative que j'ai faite pour utiliser cette approche a entraîné des erreurs car Rails s'étouffe parce que la même table de jointure Friendship est jointe à la requête deux fois.