如何禁用延迟加载活动记录查询?

时间:2017-06-06 11:50:04

标签: ruby-on-rails rails-activerecord

我想使用类似于以下内容的WHERE子句查询数据库中的某些对象:

@monuments =  Monument.where("... lots of SQL ...").limit(6)

稍后,在我看来,我使用@monuments.first之类的方法,然后循环浏览@monuments,然后显示@monuments.count

当我查看Rails控制台时,我看到Rails多次查询数据库,首先限制为1(对于@monuments.first),然后限制为6(用于循环遍历所有这些) ,最后发出一个count()查询。

如何告诉ActiveRecord只执行一次查询?只需执行一次限制为6的查询就足以获得我需要的所有数据。由于查询很慢(80毫秒),重复它需要花费很多时间。

2 个答案:

答案 0 :(得分:2)

在您的情况下,您需要在致电first之前触发查询,因为虽然firstArray上的方法,但它也是ActiveRecord上的“查找方法”将获取第一条记录的对象。

您可以使用任何需要使用数据的方法来提示。我更喜欢使用to_a,因为很明显我们将在以下处理数组:

@moments = Moment.where(foo: true).to_a
# SQL Query Executed
@moments.first #=> (Array#first) <Moment @foo=true>
@moments.count #=> (Array#count) 42

在这种情况下,您还可以使用first(6)代替limit(6),这也会触发查询。但是,对于团队中的另一位开发人员而言,这可能是不太明显的,这是有意的。

答案 1 :(得分:1)

AFAIK,@monuments.first不应该点击数据库,我在我的控制台上确认了它,也许你有多个具有相同变量的实例,或者你正在做其他事情(你还没有在这里分享),分享确切的代码和查询,我们可能会调试。

由于ActiveRecord Collections充当数组,因此您可以使用数组类比来避免查询数据库。

关于first,您可以这样做,

@monuments[0]

关于count,是的,它是一个不同的查询命中数据库,为了避免它,你可以使用length作为..

@monuments.length