0

背景

我的应用程序中有一个复杂的动态调查引擎,因此我将答案按行存储在响应表中(而不是在一个大的平面调查表中)。我现在正在生成的问题类型之一是针对所有回答具有 1-5 等级的问题的人(1 - 非常不可能...... 5 很可能)。我从 reports_controller 生成报告并将 JSON 发送到使用它们的任何报告页面。

我正在生成报告以高图表列格式显示这些。我最初遇到的问题是想要显示准确的计数,即使没有人回答该响应(即在 JSON 中发送 0 计数)。

我花了很多时间试图想出一种优雅的方法来做到这一点,并最终创建了一个默认的空零散列,然后如果答案文本匹配,则将其与我的答案合并。

我的问题...

有没有更好的方法来做到这一点?它执行良好(现在在小范围内),但似乎不太可读,并且由于 answer_text 在结果中是字符串"1" => 3而不是1 => 3,我必须使用 to_s 来匹配键。

报告控制器

question = params["question"]
format = params["report_type"]

stats = ResponseItem.joins("join table1 on table1.id = table2.table1id "\
      "join table2 on table2.id = table1.table3id "\
      "join table4 on table4.table3id = table2.id") \
      .where("table2.question_text = ? and client_id IN (?)", question, @clients.map(&:id)) \
      .select("count(*), answer_text") \
      .group("answer_text").order("answer_text").count()

case format

  when 'likely1-5'
    scale = {1 => 0, 2 => 0, 3  => 0, 4 => 0, 5 => 0}
    scale.each do |k, v|
      if stats.key?(k.to_s)
        scale[k] = stats[k.to_s].to_s
      end
      report_collection.push scale[k].to_i
    end
4

2 回答 2

1

让我们看看这是否有效。

question_id = xxx
stats = ResponseItem.select('score, count(id) as count').
                     where(question_id: question_id).
                     joins('RIGHT OUTER JOIN (SELECT "1" AS score UNION SELECT "2" UNION SELECT "3" UNION SELECT "4" UNION SELECT "5") as scores on score = answer_text').
                     group('score')
scale = stats.reduce({}) do |memo, answer_count|
  memo.merge(answer_count.score.to_i => answer_count.count)
end
于 2013-11-11T15:50:02.967 回答
1

好吧,对于初学者来说,您可以使用以下相同的基本方法简化代码:

when 'likely1-5'
  (1..5).each do |k|
    v = stats[k.to_s] || 0
    report_collection.push(v.to_i)
  end
于 2013-11-11T14:18:41.287 回答