0

我有一个问答模型,答案属于问题,一个问题有很多答案。答案有一个布尔:correct列,因此可以将答案标记为正确。

下面的代码检查一个问题是否有任何正确的答案,然后相应地显示一个不同的 div。该代码有效,但是它对我想避免的数据库执行费力的计数查询。

有没有办法重写这个查询,或者最好在问题表中有一个列,当答案被标记为正确时切换为真?

<div class="<%= question.answers.count(conditions: ['correct = ?', true]) == 1 ? 'correct-answer' : 'no-correct-answer' %>">
  <%= question.answers_count %>
</div>

编辑

感谢下面发布答案的人,但是即使在 answers 表上有一个 questions_id 索引,两个查询都使用我想避免的计数查询,因为可能有很多答案需要循环。

我的解决方案是在问题表上创建一个 :correct 布尔列,当答案被标记/切换为正确时,它也会切换该列,因此在呈现视图时我不必执行任何动态 SQL 查询。

答案.rb

def toggle_correct(attribute)
    toggle(attribute).update_attributes({attribute => self[attribute]})
  end

def toggle_question_correct
    self.question.toggle_correct(:correct)
end
4

2 回答 2

2

您正在计算该问题有多少正确答案(即检查每个答案),而您只需要检查是否存在正确答案(即一旦发现正确答案就停止)。这可以写成exists?

question.answers.exists?(:correct => true)

除非您对每个问题都有很多答案,否则它不应该显着改变响应时间。你说这部分代码很“费力”,你应该检查你是否在question_idtable的列上创建了一个索引answers。没有它,question.answers生成answers表的完整扫描。

于 2013-06-14T19:49:32.593 回答
1

我建议您在 Answer 模型上创建两个范围

scope :correct, -> { where(correct: true) }
scope :correct, -> { where(correct: false) }

那么您可以为这样的问题选择计数正确答案:

question.answers.correct.count

您可能还想在 Question 上创建一个方法

def has_correct_answer?
    ! answers.correct.count.zero?
end

如果您在单个页面上显示许多问题和答案,我建议您使用带有 where 子句的 AR#includes,这样它会减少 SQL 查询(http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple -协会

于 2013-06-14T19:41:26.087 回答