我有一个相对简单的模型设计,用于创建调查,为用户分配调查以及填写这些用户的调查。一切正常,但是当从这些调查中检索数据时,我处于一种状态,我不确定什么是正确的方法,尤其是rails方式。
我的模型设计如下:(为清楚起见只留下相关代码)
class Survey < ActiveRecord::Base
has_many :survey_sections, dependent: :destroy
has_many :survey_assignments
has_many :participants , :through => :survey_assignments, :source => :user
has_many :survey_responses
end
class SurveySection < ActiveRecord::Base
belongs_to :survey
has_many :survey_questions, dependent: :destroy
has_many :survey_options, dependent: :destroy
end
所以调查分为很多部分,每个部分都有很多问题,每个部分都有很多选项,选项基本上是当前部分所有问题的预定义答案。这是设计决定,所以我不需要每个问题都有很多选择......
class SurveyQuestion < ActiveRecord::Base
belongs_to :survey_section
has_many :survey_answers
end
class SurveyAnswer < ActiveRecord::Base
belongs_to :survey_option
belongs_to :survey_question
belongs_to :survey_response
end
class SurveyOption < ActiveRecord::Base
#it has 2 fields 'weight'(int) and 'text'(string)
belongs_to :survey_section
end
医生可以为患者分配调查,并指定他们何时可以参加调查的日期。
class SurveyAssignment < ActiveRecord::Base
#has also a field valid_until(date)
belongs_to :user
belongs_to :survey
has_many :survey_responses
end
我也在记录调查回复。因此,每次用户填写表单时,都会创建survey_responses表中的新记录。我稍后会需要这个,因为调度实现,用户可能会分配调查,他应该[在这里输入一些数字] X [day | week | month]。
class SurveyResponse < ActiveRecord::Base
belongs_to :survey_assignment
belongs_to :survey
belongs_to :user
has_many :survey_answers
end
现在我需要显示调查结果图表。就像你在代码中看到的那样,结果是整数(参见SurveyOption类),我需要将其添加到特定用户所采用的特定调查中。所以假设我有一个user_id和一个survey_id,现在我想要检索所有用户调查回复,但是对于每个调查回复,我需要他们的答案所具有的权重总和(SurveyOption)。
如果我进行以下查询,我会收到他所有答案的答案总和:
SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id:63).select("survey_option.weight").sum("weight")
但我想回答该用户对该调查的每个响应数组,如此
[[survey_response.created_at.to_i, the_sum_of_weights],[...],[...],....]
那么做这样的事情最好的方法是什么?是否可以在单个查询中执行此操作,如果我认为纯粹在sql状态中我认为这可以在单个查询中完成。
如果有人需要我进一步阐述,我们可以在评论中讨论。谢谢你的协助。
我想我想要生成的sql tatement是:
SELECT survey_responses.id, survey_responses.created_at, SUM (survey_options.weight) FROM "survey_responses" INNER JOIN "survey_answers" ON "survey_answers"."survey_response_id" = "survey_responses"."id" INNER JOIN "survey_options" ON "survey_options"."id" = "survey_answers"."survey_option_id" WHERE "survey_responses"."user_id" = 96 AND "survey_responses"."survey_id" = 64 GROUP BY survey_responses.id, survey_responses.created_at;
我想我已经接近解决我自己的问题:)))
答案 0 :(得分:0)
经过一番研究后,我发现了一种方法。
result = SurveyResponse.joins(:survey_answers => :survey_option).where(user_id: 96, survey_id: 64).select("SUM (survey_options.weight) as score, survey_responses.created_at").group("survey_responses.created_at, survey_responses.id")
然后我可以在ActiveRecord :: Relation对象上使用find_each函数。
result.find_each do |r|
puts " score: #{r.score} created_at: #{r.created_at}"
end
find_each比每个都好,因为它一次加载一批1000条记录,所以它不会占用你的记忆。想象一下,加载数百万条记录。
如果有人有更好的查询解决方案,请分享,我会接受。