2014-07-04 211 views
0

我想獲得一些嵌套查詢來獲取一些對象。下面是一些代碼rails每個迭代器迭代兩次

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 %> 

的問題是輸出爲:

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 

這就是它的迭代兩次爲什麼會發生?以及如何防止?

+0

我剛剛編輯您的HTML使其更具可讀性。你能說出你期望在第一行看到什麼嗎? –

+1

您可以使用很多'where'調用,只需使用關聯即可。例如,而不是'User.find(f.user_id.to_i).name'你不能做'f.user.name'嗎? –

+0

而你的變量命名真的讓人困惑:如果@ rank是一個Rank對象的集合,爲什麼不把它叫做'@ ranking'而不是'@ rank'呢?然後當你遍歷它時,你引用每個成員爲'f'(爲什麼??),然後讓它更加混亂,你在循環中說'f.rank'! 「Rank」類是否具有「排名」實例方法? –

回答

0

試試這個:

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

的.uniq(在該行的結尾)將刪除您的查詢返回的重複行。

1

我不是100%肯定,你想要做什麼,但你的代碼可以收拾了不少。這是一個更好的方法來做你的循環:因爲@rank是一個集合變量,我已將其重命名爲@ranks符合慣例。

<% @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

我會添加'.includes(:用戶)',以防止從'n + 1'查詢和急於加載用戶 – MrYoshiji

+0

我正要嘗試重寫控制器代碼,但是我不清楚模式是什麼。 –

0

我寫了一個SQL語句,它解決了我的問題,並把在模型文件,並把它稱爲從按鈕控制器點擊它解決了我的問題

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) 

+0

Rank.where(user_id:Application.where(stream_id:@stream.id))不會生成所需的sql – SouravMoitra