2014-07-04 3 views
0

J'essaie d'obtenir des requêtes imbriquées pour obtenir des objets. Voici le coderails chaque itérateur itératif deux fois

stream_controller.rb

def show 
    @rank = Rank.where(user_id: Application.where(stream_id: @stream.id)) 
end 

show.html.erb

<% i = 1 %> 
<% @rank.each do |f| %> 
    <tr> 
    <td><%= i %></td> 
    <td><%= f.user_id %></td> 
    <td><%= User.find(f.user_id.to_i).name %></td> 
    <td><%= f.rank %></td> 
    <tr><br> 
    <% i += 1 %> 
<% end %> 

Le problème est la sortie est:

Sr User id  Name Rank 
1 15 a16 2 
2 7 a7 a71 4 
3 8 a8 a81 6 
4 13 a14 a41 8 
5 1 a1 13 
6 4 sm 14 
7 15 a16 2 
8 7 a7 a71 4 
9 8 a8 a81 6 
10 13 a14 a41 8 
11 1 a1 13 
12 4 sm 14 

qui est son itérer deux fois pourquoi cela arrive-t-il? Et comment cela peut-il être empeché?

+0

Je vient de modifier votre code html pour le rendre plus lisible. Pouvez-vous dire ce que vous attendez de voir dans la première rangée par exemple? –

+1

Vous utilisez beaucoup d'appels 'where' où vous pouvez simplement utiliser des associations. Par exemple, au lieu de 'User.find (f.user_id.to_i) .name' ne pouvez-vous pas faire 'f.user.name'? –

+0

Et votre nom de variable est vraiment déroutant: si '@ rank' est une collection d'objets Rank pourquoi ne pas l'appeler' @ ranks' au lieu de '@ rank'? Et puis quand vous itérez dessus, vous vous référez à chaque membre comme 'f' (pourquoi ??) et ensuite pour le rendre encore plus confus vous dites' f.rank' dans la boucle! Est-ce que la classe "Rank" a une méthode d'instance "rank"? –

Répondre

0

Essayez ceci:

@rank = Rank.where(user_id: Application.where(stream_id: @stream.id)).uniq 

Le .uniq (à la fin de la ligne) va supprimer toutes les lignes en double renvoyées par votre requête.

1

Je ne suis pas sûr à 100% de ce que vous essayez de faire mais votre code pourrait être rangé un peu. Voici une meilleure façon de faire votre boucle: depuis @rank est une variable de collection, je l'ai renommé @ranks en conformité avec la convention.

<% @ranks.each_with_index do |rank, i| %> 
    <tr> 
    <td><%= i + 1 %></td> 
    <td><%= rank.user_id %></td> 
    <td><%= rank.user.name %></td> 
    <td><%= rank.rank %></td> 
    <tr><br> 
<% end %> 
+1

J'ajouterais un '.includes (: user)' pour empêcher des requêtes de 'n + 1' et impatient-charge les utilisateurs – MrYoshiji

+0

j'allais essayer de réécrire le code du contrôleur aussi mais je ne sais pas quel est le schéma. –

0

j'ai écrit une déclaration sql et il a résolu mon problème et mettre dans le fichier modèle et l'a appelé du contrôleur sur le bouton cliquez dessus résolu mon problème

def self.generate_result(stream_id) 
sql = "select distinct user_id, rank from ranks where 
     user_id = any(
     select user_id from applications where stream_id = 
     #{stream_id} 
     and verified = true) 
     order by rank asc" 
ActiveRecord::Base.connection.execute(sql) 

fin

+0

Le Rank.where (user_id: Application.where (stream_id: @ stream.id)) ne me génère pas le SQL requis – SouravMoitra