修改对象.count(conditions: []) SQL查询



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

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

是否有一种方法重写这个查询,或者最好在问题表中有一列,当答案被标记为正确时,该列被切换为true ?

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

编辑

感谢下面发布答案的家伙,然而,即使在答案表上有一个questions_id索引,两个查询都使用了我想避免的计数查询,因为很可能有相当多的答案必须循环。

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

answer.rb

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

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

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

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

我建议您在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

如果你在单页上显示许多问题和答案,我建议使用AR#包括where子句,这样它会减少SQL查询(http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations)

最新更新