3 Réponses :


0
votes

On dirait que vous êtes essentiellement modéliser un has_many: via code> relation: élément has_and_belongs_to_many utilisateur, et la note correspond au modèle de jointure. Vous pouvez lire sur : via code> relations dans le Rails Guide des associations d'enregistrement actif .

Si tel est le cas, je vous recommanderais de structurer vos relations de modèle à l'aide de has_many: via code> comme suit: p>

> items.map {|item| item.rated_by_users }
=> [[#<User id: 1, created_at: "2013-03-22 03:21:28", updated_at: "2013-03-22 03:21:28">], []] 


7 commentaires

Cela semble marcher correctement! Je suppose que c'est la réponse à Cette question aussi? Cela semble être un problème sans réponse actuelle sur le débordement de la pile (la réponse sur le lien charge tous les objets associés en mémoire et filtres par programme par programme)


J'ai rencontré un problème avec cette solution - si l'article A a une note et je interrogeons l'article B, je ne reçois pas l'article B. semble que l'existence de la notation bloque la récupération de l'autre élément?


Si l'utilisateur avec user_id 1 a une note sur l'élément 485, la demande d'élément 485 avec filtre sur user_id 2 ne renvoie aucun élément. Aucun résultat: Sélectionnez "Articles" .Id à partir de "Articles" de "Notes" "Notes" sur "Évaluations" "." Item_id "=" éléments "." ID "Où (éléments = 485) et (notes.utilisateur_id = 2 ou notes.User_id est null) Résultat Article 485: Sélectionnez "Articles" Distincts de "Articles" "Éléments" Rejoignez "Notes" sur "Nuit". "Vin_id" = "Articles". "id" où (items.id = 485) et (notes.user_id = 1 ou notes.user_id est null)


Je vois maintenant. J'ai complètement réécrit ma réponse avec une meilleure solution, s'il vous plaît regarder à nouveau


Le problème est qu'un élément peut être connecté à un grand nombre de notations. Je ne veux donc pas faire le filtrage dans le code. Si je veux faire le côté du client filtrant avec N + 1, je suppose que je pouvais faire des objets .aulwhere (...) , puis item.ratings_by_user_id (user_id) une portée avec paramètre. Mais je voudrais résoudre-le sans n + 1 requêtes .. Pensez-vous que c'est possible?


Bien, mais cela ne fait toujours pas n + 1 requêtes, il fait exactement 3 requêtes. Les instructions de sélection des évaluations et utilisateurs utilisent une clause in (...) pour rechercher n enregistrements de chacun dans une seule requête.


Mais votre solution ne filtre pas sur un utilisateur? Est-ce que cela est possible tout en ne faisant pas la n + 1 requêtes?



4
votes

Étape 1

Créer le Actual_user accessible dans le calque modèle (une technique est décrite ici: https://stackoverflow.com/a/2513456/163203 )

étape 2

Ajouter un Association avec une condition qui est évaluée pendant le temps d'exécution.

rails 2 xxx

< / strong> xxx

étape 3 xxx


4 commentaires

Travaillé parfaitement! Une petite note: la réponse à l'étape 1 que vous avez liée à ne prennent pas de précaution que la variable de fil n'est pas partagée entre les demandes. J'ai utilisé la demande de gemme_store pour que cela puisse stocker l'utilisateur actuel et vous assurer qu'il n'est pas divulgué.


Yeh il ressemble à mince et puma Les serveurs ont des problèmes. BTW, le gemme utilise fil.current magasin, ils l'effacent après l'appel.


J'ai corrigé la question de la fuite de fil dans la solution suggérée à l'étape 1.


Je pense que mettre le actuel_user sur le calque modèle est faux. Il y a une meilleure solution pour ce cas.



1
votes

Comme je l'ai récemment écrit dans Ce message de blog , je suggérerais ce qui suit dans votre cas:

items = Item.all
ActiveRecord::Associations::Preloader.new.preload(items, :ratings, Rating.where(user_id: user_id))


0 commentaires