当我尝试遍历一个包含来自两个表的记录的数组时,如果它无法从另一个记录中找到该属性,则会出错。
该数组有两种不同类型的元素。一个开头是:#<Question id: 1,
,另一个以#<Answer id: 1,
开头。如果没有它在另一个中寻找它,你如何得到一个的价值?
错误:
undefined method `option' for #<Question:0x007fcc2c6610e8>
如何在需要时绕过或遍历此数组以显示属性值?
控制器:
@pdf = []
@test = Test.find(params[:id])
@test_questions = @test.questions
answers = Answer.all
@all_answers = answers.group_by(&:question_id)
@test_questions.each do |q|
@pdf << q
@pdf += @all_answers[q.id]
end
我试图仅显示内容属性值的html,然后是所有选项属性值
<tbody>
<% @pdf.each do |test| %>
<tr>
<td><%= test.id %></td>
<% if test.content %>
<td><%= test.content %></td>
<% end %>
<% if test.option %>
<td><%= test.option %></td>
<% end %>
</tr>
<% end %>
</tbody>
这就是数组的样子:
[#<Question id: 1, content: "How did the chicken cross the road?", question_type: "MC", category: "ip_voice", product_id: 8, active: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14", user_id: 1>, #<Answer id: 1, option: "It walked", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 2, option: "It was thrown", question_id: 1, correct: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 3, option: "It got run over and pushed", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Question id: 2, content: "Is this working?", question_type: "TF", category: "ip_voice", product_id: 6, active: true, reated_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53", user_id: 1>, #<Answer id: 4, option: "False", question_id: 2, correct: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">, #<Answer id: 5, option: "True", question_id: 2, correct: false, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">]
尝试使用SimonW
<% @options = [] %>
<% @test_questions.each do |q| %>
<tr>
<td width="40px;">1.</td>
<td><%= q.content %></td>
<% @all_answers.each do |a| %>
<% @options << a.find(q.id) %>
<% end %>
</tr>
<% @options.each do |o| %>
<tr>
<%= o.option %>
</tr>
<% end %>
<% end %>
错误:
undefined method `option' for #<Enumerator:0x007fcc4181e678>
答案 0 :(得分:2)
尝试改为:
@test = Test.find(params[:id])
@test_questions = @test.questions
answers = Answer.all
@all_answers = answers.group_by(&:question_id)
@pdf = @test_questions.map { |q| [q, @all_answers[q.id]] }
然后在视图中:
<tbody>
<% @pdf.each do |question, answers| %>
<tr>
<td><%= question.id %></td>
<td><%= question.content %></td>
<% answers.each do |answer|
<td><%= answer.option %></td>
<% end %>
</tr>
<% end %>
</tbody>
控制器:
@test_questions = @test.questions.includes(:answers)
查看:
<tbody>
<% @test_questions.each do |question| %>
<tr>
<td><%= question.id %></td>
<td><%= question.content %></td>
<% question.answers.each do |answer|
<td><%= answer.option %></td>
<% end %>
</tr>
<% end %>
</tbody>
答案 1 :(得分:1)
您可以使用respond_to?
来避免该错误,并确保您不会在不知道如何处理它的对象上调用option
方法:
<% if test.respond_to?(:option) && test.option %>
答案 2 :(得分:0)
如何通过对选项方法(鸭子打字)的响应迭代对象,无论如何我同意SimonW认为这是一个糟糕的设计:
<% @options.select{|i| i.respond_to?(:option)}.each do |o| %>
<tr>
<%= o.option %>
</tr>
<% end %>