2016-05-13 73 views
0

我正在使用ActiveRecord的rails項目。我正在做一些循序漸進的查詢,由於我是Activerecord的新手,似乎缺少關鍵概念。我無法在模型上獲得標識,因此無法執行查詢。這裏是我的代碼:無法獲得RoR Active記錄模型ID來執行查詢

questions = JSON.parse(q) 
selected_answers = questions.map do |ques| 
    ques['options'].map do |opt| 
    Answer.where(value: opt['title']) 
    end 
end 

participants = selected_answers.flatten!.map do |sa| 
    Participant.where(answers: sa.id) 
end 

stats[:answers] = participants.map do |p| 
    Answer.where(participants: p.id) #this line causes an error 
end 

我得到錯誤

NoMethodError (undefined method `id' for #<Participant::ActiveRecord_Relation:0x007fc478423bc0>): 
    app/services/survey_statistics.rb:143:in `block in get_question' 
    app/services/survey_statistics.rb:142:in `map' 
    app/services/survey_statistics.rb:142:in `get_question' 
    app/services/survey_statistics.rb:25:in `block in questions' 
    app/services/survey_statistics.rb:22:in `questions' 
    app/controllers/api/v1/reports_controller.rb:13:in `questions' 
+0

它看起來像你的變量'參與者'是一個集合的集合。此鏈接可能會幫助您:http://stackoverflow.com/questions/27021036/undefined-method-id-for-activerecordrelation – Pholochtairze

回答

0

@ Pholochtairze的答案是當場上。這個答案是刪除所有這些電話來映射,並有效地得到你需要的所有答案(雙關語意:p)

首先你會得到所選答案的列表。我們將把所有標題保存到一個不同的變量中,並用它來獲得所有的答案。我們還將使用flat_map作爲最外層循環。與flatten!!方法

questions = JSON.parse(q) 

titles = questions.flat_map do |ques| 
    ques['options'].map { |opt| opt['title'] } 
end 

selected_answers = Answer.where(value: titles) 

一個問題是,他們返回零的時候沒有做,因爲你通常不希望在鏈使用它們的變化。因此,這裏的重構是將的呼叫轉移到where方法中。

participants = Participant.where(answers: selected_answers.map(&:id)) 

更好的重構是使用pluck,而不是map因爲selected_answers現在是一個ActiveRecord::Relation對象。這將阻止Rails不必要地創建記錄。

participants = Participant.where(answers: selected_answers.pluck(:id)) 

對於最後一部分,我們希望爲我們之前得到的參與者獲得答案。您仍然可以使用map,但我們再次使用pluck來提高效率。

stats[:answers] = Answer.where(participants: participants.pluck(:id)) 

而你有它。

0

看起來participants是集合的集合。你正在使用map,所以你的變量p現在是一個集合(實際上Participant::ActiveRecord_Relation告訴你它是一個集合),這就是爲什麼它沒有id

stats[:answers] = participants.map do |p| 
    p.map do |p1| 
    Answer.where(participants: p1.id) 
    end 
end 

您可以在這裏找到一個相關的問題:我要再次通過收集(在p一個這一次)如下嘗試循環undefined method `id' for #<ActiveRecord::Relation []>

0

,因爲你做了地圖它不工作它構造一個數組其中也返回數組相結合,讓你有數組的數組:

stats[:answers] = participants.map do |p| 
    Answer.where(participants: p.id) #this line causes an error 
end 

可以的政績已經你的目標更簡單,據我瞭解你的業務邏輯可以替代所有的代碼與此:

questions = JSON.parse(q) 
titles = questions.each_with_object([]) do |q, a| 
    q["options"].each { |option| a << option["title"] } 
end 

participants_ids = Answer.where(value: titles).pluck(:participant_id) 
stats[:answers] = Answer.where(participant_id: participant_ids)