为什么 Rails 3 中的 Model.all 与 Model.where('true') 不同

发布于 2024-11-10 05:33:44 字数 312 浏览 0 评论 0原文

我有一个查询,效果很好:

ModelName.where('true')

我可以将其与其他 AR 调用(例如 where、order 等)链接起来。但是,当我使用时:

ModelName.all

我收到“相同”响应,但无法将 where 或 order 链接到它,因为它是数组而不是 AR 集合。 虽然我使用第一种方法没有任何实际问题,但它似乎有点丑陋/不必要。有没有更干净的方法可以做到这一点,可能是 .to_active_record_collection 或其他什么?

I have a query, which works fine:

ModelName.where('true')

I can chain this with other AR calls such as where, order etc. However when I use:

ModelName.all

I receive the "same" response but can't chain a where or order to it as it's an array rather than a AR collection.
Whereas I have no pragmatic problem using the first method it seems a bit ugly/unnecessary. Is there a cleaner way of doing this maybe a .to_active_record_collection or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

謸气贵蔟 2024-11-17 05:33:45

正如您所说,后者返回一个元素数组,而前者是一个 ActiveRecord::Relation。您可以使用 Ruby 方法对数组进行排序和过滤。例如,要按 id 排序,您可以调用 sort_by(&:id)。要过滤元素,您可以调用 selectreject。对于 ActiveRecord::Relation 您可以将 whereorder 链接到它,正如您所说。

区别在于排序和处理的位置。对于Array来说,是由应用程序完成的;对于关系 - 通过数据库。当记录更多时,后者通常更快。它的内存效率也更高。

As you said, the latter returns an array of elements, while the former is an ActiveRecord::Relation. You can order and filter array using Ruby methods. For example, to sort by id you can call sort_by(&:id). To filter elements you can call select or reject. For ActiveRecord::Relation you can chain where or order to it, as you said.

The difference is where the sorting and processing goes. For Array, it is done by the application; for Relation - by the database. The latter is usually faster, when there is more records. It is also more memory efficient.

锦欢 2024-11-17 05:33:44

有一个简单的解决方案。而不是使用

ModelName.where('true')

使用:

ModelName.scoped

There is an easy solution. Instead of using

ModelName.where('true')

Use:

ModelName.scoped
女皇必胜 2024-11-17 05:33:44

正如您所说:

ModelName.where('true').class #=> ActiveRecord::Relation

ModelName.all.class #=> Array

因此,只要不使用触发查询的 allfirstlast ,您就可以进行尽可能多的延迟加载。

当您考虑缓存时,了解这些差异非常重要。

我仍然无法理解什么样的情况会导致您遇到类似的情况:

ModelName.all.where(foobar)

...除非您需要整堆资产用于一个目的,并从数据库中加载它,并需要其中的一个子集用于其他目的。对于这种情况,您需要使用 ruby​​ 的数组过滤方法。


旁注:

 ModelName.all

永远不应该使用,它是一种反模式,因为您无法控制要检索的项目数量。并希望:

 ModelName.limit(20).class #=> ActiveRecord::Relation

As you said:

ModelName.where('true').class #=> ActiveRecord::Relation

ModelName.all.class #=> Array

So you can make as many lazy loading as long as you don't use all, first or last which trigger the query.

It's important to catch these differences when you consider caching.

Still I can't understand what kind of situation could lead you to something like:

ModelName.all.where(foobar)

... Unless you need the whole bunch of assets for one purpose and get it loaded from the database and need a subset of it to other purposes. For this kind of situation, you'd need to use ruby's Array filtering methods.


Sidenote:

 ModelName.all

should never be used, it's an anti-pattern since you don' control how many items you'll retrieve. And hopefully:

 ModelName.limit(20).class #=> ActiveRecord::Relation
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文