Можете ли вы вызвать all
для этого объекта, чтобы по существу привести его к массиву?
Item.select("items.*").from(source).includes([:images]).all.count
Или, возможно, в этом случае size
будет более подходящим.В любом случае это выполнит запрос и загрузит все объекты в память, что может быть нежелательно.
Похоже, проблема в вашем includes([:images])
.В аналогичном приложении я могу выполнить это из консоли:
> Category.select('categories.*').from('(SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories').count
(0.5ms) SELECT COUNT(*) FROM (SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories
(Обратите внимание, что count
переопределяет предложение SELECT, хотя я явно указал items.*
. Но они по-прежнему эквивалентны запросам.)
Как только я добавляю область действия includes
, она выходит из строя:
> Category.select('categories.*').from('(SELECT DISTINCT source.* FROM (SELECT * FROM categories) AS source) AS categories').includes(:projects).count
NoMethodError: undefined method `left' for #<Arel::Nodes::SqlLiteral:0x131d35248>
Я попробовал несколько различных способов получения счетчика, например select('COUNT(categories.*)')
, но все онине удалось по-разному.ActiveRecord, похоже, использует базовый LEFT OUTER JOIN для выполнения активной загрузки, возможно, потому, что он думает, что вы используете какое-то условие или внешнюю таблицу для выполнения соединения, и это, кажется, путает его обычные методы выполнения подсчета,См. Конец раздела «Стремительная загрузка» в ActiveRecord::Associations
документах .
Мое предложение
Если объединение не влияет на количество строк, возвращаемых ввнешний запрос, я бы сказал, что вам лучше всего выполнить один запрос для подсчета и один запрос для получения фактических результатов.Мы должны сделать нечто подобное в нашем приложении для подкачки страниц: один запрос возвращает текущую страницу результатов, а другой возвращает общее количество записей, соответствующих критериям фильтра.