3

我想保存一个查询,然后在它之上构建,然后执行它。

例如,不知何故

query = Post.order('likes DESC') # buffer the query
query = query.limit(3) # add on top of it
query.run # run it - this is the wrong syntax fyi

这可以做到吗?什么是正确的语法?

PS。我不确定“缓冲区”是否是正确的词,如果我错了,请纠正我。

谢谢!

4

4 回答 4

4

在 Rails 3 中使用 ActiveRecord 构建查询时,您不需要任何“缓冲区”,因为它使用Arel。您query = Post.order('likes DESC')为您提供了 ActiveRecord::Relation 的实例。此对象包含有关查询的信息,但不是实际数据。例如,要获取数据,您可以调用.first.all方法。这是rails框架(> = 3.0)实现所谓的“延迟初始化”的方式。这意味着 ActiveRecord::Relation 是一种代理。仅当您尝试获取模型的某些字段时(或者当您使用 .all 等强制加载数据时)才会对数据库进行真正的.first查询.last。在此操作之前,您可以构建过滤条件链并确保您不会“干扰”数据库。你的代码可能是这样的:

query = Post.order('likes DESC') # ActiveRecord::Relation object with info about your query
query = query.limit(3) # adds more filtering options
@posts = query.all # here ActiveRecord takes data from the database

#239 ActiveRecord::Relation 演练将使您对 ActiveRecord::Relation 有更多的了解

于 2012-10-24T11:37:58.020 回答
3

如果您使用 AREL 和 Rails 3,这会自动发生。AREL 将在您链接选项时构建一个查询,并在您调用.all或开始通过任何其他方式访问数据时执行查询。

于 2012-10-24T03:10:35.653 回答
2

这正是 ActiveRecord 的工作原理。当它遇到迭代器或其他一些非 AR 方法时,它会使用构建的查询调用数据库。它在控制台中的工作方式略有不同,因为我相信.inspect在您按下回车后会调用该方法来显示输出。

按照你的建议去做就好了。

于 2012-10-24T03:10:55.113 回答
0

您可以使用ActiveRecord::Relation#load方法强制数据库命中:

https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-load

于 2019-06-10T06:53:20.697 回答