2016-05-13 6 views
0

私はActiveRecordを使用しているrailsプロジェクトに取り組んでいます。私はいくつかの段階的な質問をしています、そして、私はActiverecordを初めて知っているので、私はキーコンセプトが欠けているようです。私はモデル上でIDを取得することができず、結果としてクエリを実行することができません。私はエラーがそれはparticipantsのように見えるRoRアクティブレコードモデルIDを取得できませんでした。

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) 

1つの問題は、あなたが通常チェーンにそれらを使用したくないので、作られた変化がないとき、彼らはnilを返すということです。したがって、大きなリファクタは、whereメソッドの中でmapにコールを移動することです。

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

良好リファクタリングはselected_answers以来pluck代わりにmapは現在ActiveRecord::Relationオブジェクトで使用することです。これにより、Railsがレコードを不必要に作成するのを防ぐことができます。

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

最終的には、私たちが以前に持っていた参加者の回答を得たいと思います。 mapは引き続き使用できますが、効率を上げるためにpluckを使用します。

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

これがあります。

0

はコレクションのコレクションで取得

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 

:ここに私のコードです。 mapを使用していますので、変数pがコレクションになりました(実際にはParticipant::ActiveRecord_Relationがコレクションだと伝えています)。そのため、idがありません。

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

はあなたがここに関連する問題を見つけることができます:私は再び次のようにコレクション(p 1この時間)をループにしようとundefined method `id' for #<ActiveRecord::Relation []>

0

あなたがマップをしたので、それは動作しません

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

あなたがachieことができます:あなたは、配列の配列を持っているので、これは、また、配列を返すと組み合わせ配列を構築します限り、私はあなたのビジネスロジックを理解できるように、あなたはこれですべてのコードを置き換えることができ、あなたの目標は、はるかに簡単まし:

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) 
関連する問題