почему Model.all отличается от Model.where ('true') в рельсах 3 - PullRequest
2 голосов
/ 28 мая 2011

У меня есть запрос, который отлично работает:

ModelName.where('true')

Я могу связать это с другими вызовами AR, такими как, где, порядок и т. Д. Однако, когда я использую:

ModelName.all

Я получаю "тот же самый" ответ, но не могу связать его в порядке или порядке, поскольку это массив, а не коллекция AR. В то время как у меня нет никаких прагматических проблем с использованием первого метода, он кажется немного уродливым / ненужным. Есть ли более чистый способ сделать это, может быть .to_active_record_collection или что-то?

Ответы [ 3 ]

5 голосов
/ 28 мая 2011

Есть простое решение.Вместо использования

ModelName.where('true')

Использование:

ModelName.scoped
3 голосов
/ 28 мая 2011

Как вы сказали:

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

ModelName.all.class #=> Array

Таким образом, вы можете выполнить столько отложенной загрузки, сколько не используете all, first или last, которые запускают запрос.

Важно уловить эти различия, когда вы рассматриваете кеширование.

Тем не менее я не могу понять, какая ситуация может привести вас к чему-то вроде:

ModelName.all.where(foobar)

...Если вам не нужен весь набор ресурсов для одной цели, а также его загрузка из базы данных и подмножество его для других целей.В такой ситуации вам необходимо использовать методы фильтрации массивов ruby.


Sidenote:

 ModelName.all

никогда не следует использовать, это анти-шаблон, так как вы не используете'контролировать, сколько предметов вы получите.И, надеюсь,:

 ModelName.limit(20).class #=> ActiveRecord::Relation
1 голос
/ 28 мая 2011

Как вы сказали, последний возвращает массив элементов, а первый - ActiveRecord::Relation. Вы можете упорядочить и отфильтровать массив, используя методы Ruby. Например, для сортировки по идентификатору вы можете позвонить sort_by(&:id). Для фильтрации элементов вы можете позвонить select или reject. Для ActiveRecord::Relation вы можете связать where или order, как вы сказали.

Разница в том, куда идет сортировка и обработка. Для массива это делается приложением; для связи - по базе. Последний обычно быстрее, когда есть больше записей. Это также более эффективно для памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...