我有一个查询,工作正常:
ModelName.where('true')
我可以将其与其他AR调用链接,例如where,order等。但是当我使用时:
ModelName.all
我收到“相同”的回复,但无法将地址或订单链接到它,因为它是数组而不是AR集合。 虽然我没有使用第一种方法的实用问题,但似乎有点难看/不必要。有没有一种更干净的方式可以这样做.to_active_record_collection或什么?
答案 0 :(得分:5)
有一个简单的解决方案。而不是使用
ModelName.where('true')
使用:
ModelName.scoped
答案 1 :(得分:3)
正如你所说:
ModelName.where('true').class #=> ActiveRecord::Relation
ModelName.all.class #=> Array
因此,只要您不使用触发查询的all
,first
或last
,就可以进行尽可能多的延迟加载。
在考虑缓存时,了解这些差异非常重要。
我仍然无法理解什么样的情况会导致你:
ModelName.all.where(foobar)
...除非您需要将一大堆资产用于一个目的并从数据库中加载它并将其子集用于其他目的。对于这种情况,您需要使用ruby的Array过滤方法。
旁注:
ModelName.all
永远不应该使用,这是一种反模式,因为你无法控制你将检索多少项目。并希望:
ModelName.limit(20).class #=> ActiveRecord::Relation
答案 2 :(得分:1)
正如你所说,后者返回一个元素数组,而前者是ActiveRecord::Relation
。您可以使用Ruby方法对数组进行排序和过滤。例如,要按ID排序,您可以调用sort_by(&:id)
。要过滤元素,您可以调用select
或reject
。对于ActiveRecord::Relation
,您可以将where
或order
链接到它,如您所说。
区别在于分类和处理的位置。对于Array,它由应用程序完成; for Relation - 由数据库。当记录更多时,后者通常更快。它的内存效率也更高。