我想使用类似于以下内容的WHERE子句查询数据库中的某些对象:
@monuments = Monument.where("... lots of SQL ...").limit(6)
稍后,在我看来,我使用@monuments.first
之类的方法,然后循环浏览@monuments
,然后显示@monuments.count
。
当我查看Rails控制台时,我看到Rails多次查询数据库,首先限制为1(对于@monuments.first
),然后限制为6(用于循环遍历所有这些) ,最后发出一个count()查询。
如何告诉ActiveRecord只执行一次查询?只需执行一次限制为6的查询就足以获得我需要的所有数据。由于查询很慢(80毫秒),重复它需要花费很多时间。
答案 0 :(得分:2)
在您的情况下,您需要在致电first
之前触发查询,因为虽然first
是Array
上的方法,但它也是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