我有一个问答模型,答案属于问题,一个问题有很多答案。答案有一个布尔: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)
除非你对每个问题都有很多答案,否则它不应该显著改变响应时间。您说这部分代码"费力",您应该检查是否在表answers
的question_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)