2010-01-18 6 views
4

J'utilise Rails 2.3.5.Comment trouver uniquement les utilisateurs qui ont posté au moins un commentaire

Ceci est un cas standard. Les tables sont: users, comments, user_comments. J'ai besoin de trouver tous les utilisateurs qui ont un statut 'actif' et ont posté au moins un commentaire.

Je sais que la table des commentaires peut avoir une clé étrangère mais c'est un exemple artificiel. Il y a deux utilisateurs dans la table. Il y a deux commentaires. Les deux commentaires sont postés par le premier utilisateur.

named_scope :with_atleast_one_comment, lambda { { 
     :joins => 'inner join user_comments on users.id = user_comments.user_id ' } } 


named_scope :with_active_status, {:conditions => {:status => 'active'} }  

Lorsque j'exécute

User.with_atleast_one_comment.with_active_status 

je reçois deux enregistrements. Comme les deux commentaires sont postés par un utilisateur, je ne veux qu'un seul utilisateur.

Quelle est la solution?

Répondre

5

La portée with_at_least_one_comment ne se comporte pas comme prévu. Comme il apparaît dans la question, il sélectionnera un utilisateur pour chaque entrée dans user_comments. Ce qui entraîne les résultats en double que vous voyez. Une fois composé avec active_users, vous supprimerez tous les enregistrements renvoyés par with_at_least_one_comment qui n'ont pas d'état actif.

Commençons par simplifier la portée nommée problématique en premier. Vous n'avez pas besoin de lambda car il n'y a pas d'arguments à prendre, et la jointure peut être sous-traitée à l'enregistrement actif, qui effectue une jointure interne si une association est donnée.

En bref, cette portée nommée fera exactement ce que vous voulez.

named_scope :with_at_least_one_comment, :joins => :user_comments, 
    :group => 'users.id' 
0

Spécifiez l'option: uniq => true pour supprimer les doublons de la collection. Ceci est très utile en conjonction avec l'option: through.

+0

ArgumentError: Unknown clé (s): Uniq si je named_scope: with_atleast_one_comment, lambda {{ : uniq => true, : jointures => 'jointure interne commentaires_utilisateur sur users.id = utilisateur_comments.user_id'}} –

+0

-1: uniq n'est pas une option valide pour une étendue nommée. – EmFi

0

si je suis est pas mal, il y a peu de moyen d'y parvenir ...
moins User.comments?
ou d'une autre manière est précise également une nouvelle méthode dans votre contrôleur et enfin ...
l'info de Emfi devrait fonctionner un essai pour elle ~

+0

Vos suggestions ne sont pas mauvaises. Mais ils nient les avantages de named_scopes. Quelle est l'optimisation de la population retardée des objets ActiveRecord jusqu'à ce que seuls les enregistrements souhaités soient sélectionnés. S'appuyant sur une nouvelle méthode de contrôleur ou à moins d'user.comments, il faut sélectionner tous les utilisateurs remplissant les objets AR et rejeter ceux qui ne le sont pas. Ce qui se traduira par de très grandes requêtes SQL/réponses, ralentissement majeur sous un usage intensif et pourrait éventuellement se passer de la pagination. – EmFi

+0

oui ... vous avez raison ~ ma faute ne fait rien à propos de la performance de l'application alors ... dernière conclusion la réponse de Emfi est le meilleur ... – 1myb

Questions connexes