Yule
Yule

Reputation: 9764

why is Model.all different to Model.where('true') in rails 3

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?

Upvotes: 2

Views: 1039

Answers (3)

apneadiving
apneadiving

Reputation: 115541

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

Upvotes: 3

Yule
Yule

Reputation: 9764

There is an easy solution. Instead of using

ModelName.where('true')

Use:

ModelName.scoped

Upvotes: 5

Miki
Miki

Reputation: 7188

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.

Upvotes: 1

Related Questions