我读了几个问题并安装了Bullet gem以避免N + 1问题,但仍然没有运气。我使用Postgre
我正在开发一个考试应用,课程是:
我需要生成报告,例如,通过能力,内容,每个学生的成功列表等成功分类,等等。
我实际上是通过控制器管理这个代码,如下所示:
建立一个表格,其中包含一项评估中包含的能力,问题数量以及每个能力课程成功率的百分比
def habilidad_pme
@pme_abilities = @instrument.evaluation.questions.map{|q| q.pme_ability }.uniq
@pme_table = []
@pme_abilities.each do |pmea|
nombre_pmea = pmea.nombre
cantidad_preguntas = @instrument.evaluation.questions.map{|q| q if q.pme_ability_id == pmea.id }.compact.count
ccpme = cantidad_correctas_pme(pmea)
porcentaje = @asistencia > 0 ? (ccpme/(cantidad_preguntas*@asistencia.to_f)*100).to_i : 0
@pme_table << { nombre_pme: nombre_pmea, cantidad_preguntas: cantidad_preguntas, porcentaje: porcentaje }
end
@pme_table
end
def cantidad_correctas_pme(pme)
preg = @instrument.evaluation.questions.map{|q| q if q.pme_ability_id == pme.id }.compact
correctas = 0
preg.each do |p|
Answer.where(question_id: p.id, proccess_instrument: @proccess_instrument).each do |a|
if a.letra == @instrument.guides.find_by(question_id: p.id).alternative_index
correctas+=1
end
end
end
correctas
end
每个问题的正确答案数量
def cantidad_correctas(question)
correctas = 0
Answer.where(question_id: question.id, proccess_instrument: @proccess_instrument).each do |a|
if a.letra == @instrument.guides.find_by(question_id: question.id).alternative_index
correctas+=1
end
end
correctas
end
按能力内容
分组的问题的正确答案数量def habilidad_contenido_pme
@pmes = @instrument.evaluation.questions.map{ |q| q.pme_ability }.uniq
@pme_content_table = []
@pmes.each do |pm|
pme_parcial = []
preguntas_pme = @instrument.evaluation.questions.where(:pme_ability_id => pm.id).joins(:content).group('contents.id').count
preguntas_pme.each do |key,value|
contenido = Content.find(key.to_i)
cc = cantidad_correctas_pme_contenido(pm,contenido)
porcentaje = @asistencia > 0 ? (cc/(value*@asistencia.to_f)*100).to_i : 0
pme_parcial << {nombre_pme: pm.nombre, nombre_contenido: contenido.nombre, cantidad_preguntas: value, porcentaje: porcentaje }
end
@pme_content_table << pme_parcial
end
@pme_content_table
end
def cantidad_correctas_pme_contenido(pme,content)
preg = @instrument.evaluation.questions.map{|q| q if q.pme_ability_id == pme.id && q.content_id == content.id }.compact
correctas = 0
preg.each do |p|
Answer.where(question_id: p.id, proccess_instrument: @proccess_instrument).each do |a|
if a.letra == @instrument.guides.find_by(question_id: p.id).alternative_index
correctas+=1
end
end
end
correctas
end
工作,但在我看来它很慢,我必须使用这样的方法大约每次报告10次(使用不同的问题属性),一个班有30个学生,每个学生回答大约30个问题。
生成1个报告大约需要40秒-1分钟,每次生成报告时rails日志都会变得疯狂,查询量很大。
我认为这里的解决方案是每个表使用1个大查询,但我无法找到开始的方法。
问候
答案 0 :(得分:0)
我只能假设模型(关系)的样子,所以你可能需要调整以下内容才能工作。可能有一个比这更优化的解决方案,但我不想改变你的实现。
def habilidad_pme
@pme_abilities = PmeAbility.includes(question: {evaluation: :instrument}).where(instruments: {id: @instrument.id})
@pme_table = []
@pme_abilities.find_each do |pmea|
nombre_pmea = pmea.nombre
cantidad_preguntas = @instrument.evaluation.questions.where(pme_ability_id: pmea.id).count
ccpme = cantidad_correctas_pme(pmea)
porcentaje = @asistencia > 0 ? (ccpme/(cantidad_preguntas*@asistencia.to_f)*100).to_i : 0
@pme_table << { nombre_pme: nombre_pmea, cantidad_preguntas: cantidad_preguntas, porcentaje: porcentaje }
end
@pme_table
end
def cantidad_correctas_pme(pme)
preg = @instrument.evaluation.questions.where(pme_ability_id: pme.id)
correctas = 0
preg.find_each do |p|
correctas += Answer.where(question_id: p.id, proccess_instrument: @proccess_instrument, letra: @instrument.guides.find_by(question_id: p.id).alternative_index).count
end
correctas
end
使用此作为参考,您现在也应该能够优化其他参考。