2010-04-14 6 views
0

Je cherche de l'aide avec l'optimisation Ruby concernant le chargement des associations sur demande.Y compris l'optimisation des associations dans Rails

Cet exemple est simplifié. J'ai 3 modèles: Post, Comment, User. Les références sont: Post a beaucoup de commentaires et Comment a référence à User (: auteur). Maintenant, quand je vais à la page de post, je m'attends à voir le corps du message + tous les commentaires (et leurs noms d'auteurs respectifs). Cela nécessite la suite 2 requêtes:

select * from Post -- to get post data (1 row) 
select * from Comment inner join User -- to get comment + usernames (N rows) 

Dans le code que j'ai:

Post.find(params[:id], :include => { :comments => [:author] } 

Mais cela ne fonctionne pas comme prévu: que je vois à l'arrière, il es toujours N + 1 hits (certains d'entre eux sont mis en cache cependant). Comment puis-je optimiser cela?

UPD Après enquête, il semble que le code est correct, mais il ne fonctionne pas comme prévu au cas où j'ai nommé belongs_to dans un modèle de commentaire. Une fois que j'ai changé de: auteur à: utilisateur, cela a fonctionné comme prévu.

Répondre

1

Si vous êtes satisfait de 2/3 requêtes, vous pouvez essayer:

@post = Post.find params[:id] 
@comments = Comments.find_by_post_id(params[:id], :include => [:author]) 

ou

@comments = @post.comments(:include => [:author]) 

Edit: Avez-vous essayé avec:

Post.find (params [ : id],: include => {: comments =>: auteur}

+0

Je l'ai juste à côté de la dernière variante, et voir encore qu'il charge auteurs séparément (base de données frapper plus d'une fois, par le nombre de commentaires). – Vitaly

+0

http://guides.rubyonrails.org/active_record_querying.html#nested-associations-hash, on dirait que vous pouvez nicher comprend – Corey

+0

@Corey - oui, je suivais cet article comme vous pouvez le voir dans mes questions, mais cela a fait Ne fonctionne pas comme prévu. – Vitaly

1

Dans mon projet, j'ai une relation similaire à votre Post, Comment, et User modèles. Je vois seulement trois requêtes sql réelles.

Post.find(1, :include => { :comments => [:author] }) 

Dans le journal de débogage il montre ces trois requêtes

SELECT * FROM `posts` WHERE (`posts`.`id` = 1) 
SELECT `comments`.* FROM `comments` WHERE (`comments`.`post_id` = 1) 
SELECT * FROM `authors` WHERE (`authors`.`id` IN (4,8,15,16,23,42)) 
+0

J'ai mis à jour, il change la façon dont il tire les utilisateurs (auteurs) en fonction de ce que j'ai dans belongs_to. – Vitaly

+0

Avez-vous étudié comment on peut commander des commentaires en créant une date desc? – Vitaly

+0

donc vous voulez dire ceci ?: Post.find (1,: include => {: commentaires =>: auteur},: order => 'comments.created_at desc') – Corey