在测试空的ActiveRecord结果时,是否有一种干净的方法来避免双重查询?

时间:2014-08-24 18:36:57

标签: ruby-on-rails activerecord

在.html.erb文件中,编写类似这样的内容是很自然的:

<% unless @results.empty? %>
  <ul>
    <% @results.each do |result| %>
      <li>
        <%= link_to result.name, '#' %> 
      </li>
    <% end %>
  </ul>
<% end %>

其中@results是ActiveRecord .all查询的结果。不幸的是,这会向数据库生成两个查询:第一个查找结果计数(除非条件),第二个查找实际结果。在这种情况下,查询特别昂贵。

我可以简单地将结果转换为数组(可以缓冲整个结果集),或者将复杂逻辑转换为.erb

这两种解决方案似乎都不符合Rails / ActiveRecord的设计理念。

有没有更好的方法来消除重复的查询?

1 个答案:

答案 0 :(得分:3)

Rails试图变得聪明,并且在不需要它时不加载整个关联/关系。因此,关系或关联的一些方法看起来像Enumerable的对应方,但如果未加载关联,则会运行一些sql。 firstany?include?就是一个例子。

最简单的方法,当您知道这种优化未得到回报的情况时,就是强制加载关系。您可以通过转换为数组to_a来实现此目的,但您也可以更直接。

@results = Foo.where(...).load

这也将@results保持为关系而不是转换为数组。