Хорошо, спасибо tadman за то, что подтолкнули меня в правильном направлении.
Я копал немного глубже (особенно в файлах журналов), и то, что я нашел, немного странно.
Проблема была вызвана количеством выбранных столбцов. Если выбрать только один столбец и считать результат
my_meal.noodles.select("distinct color").count
ActiveRecord создает следующий оператор SQL:
SELECT COUNT(distinct color) AS count_id FROM "NOODLES" WHERE ("NOODLES".meal_id = 295)
В случае, если один выбирает два или более столбца и применяет к нему count
my_meal.noodles.select("distinct color, shape").count
ActiveRecord забывает об этом предложении select и создает:
SELECT COUNT(*) AS count_id FROM "NOODLES" WHERE ("NOODLES".meal_id = 295)
Это может быть правильно, поскольку (SQL) COUNT
допускает использование только одного или нескольких столбцов в качестве параметров. Добавьте group
перед count
и все в порядке:
my_meal.noodles.select("distinct color, shape").group("color, shape").count
SELECT COUNT(*) AS count_all, color, shape AS color_shape FROM "NOODLES" WHERE ("NOODLES".meal_id = 295) GROUP BY color, shape
Помимо этого AS color_shape
это именно то, что я ожидал. НО ... только это возвращает это:
>> my_meal.noodles.select("distinct color, shape").group("color, shape").count
=> {star=>309, circle=>111, spaghetti=>189, square=>194, triangle=>179, bowtie=>301, shell=>93, letter=>230}
>> my_meal.noodles.select("distinct color, shape").group("color, shape").count.class
=> ActiveSupport::OrderedHash
Это странное возвращаемое значение (кроме порядка, зависящего от БД) идентично результату и возвращаемому значению
my_meal.noodles.group("shape").count
Вывод:
Как указывало , здесь все еще существует разрыв между отношениями (могут быть математическими или относительными) и ActiveRecord :: Relations.
Я вижу преимущества использования результата в шаблонах модели как можно чаще (по крайней мере, в контексте приложения Rails).
Однако реальные отношения являются не результатом комбинации нескольких операций, а результатом объединения этих операций.
В целом, цепочка ActiveRecord :: Relations - отличная вещь, но есть некоторые конструктивные решения, которым я не могу следовать.
Если вы не можете полагаться на уверенность в том, что каждое действие возвращает новое отношение для работы, оно теряет большую часть своей первоначальной привлекательности.
Что касается решения моей проблемы, я буду использовать вышеупомянутое решение group
и какой-то грязный обходной путь для операции подсчета:
my_meal.noodles.select("distinct color, shape").group("color, shape").all.count
Это сжимает результаты до приемлемого минимума, прежде чем извлекать их из базы данных и создавать дорогие объекты, чтобы просто посчитать их. В качестве альтернативы можно использовать рукописный SQL-запрос, но зачем иметь Rails и не использовать его, а? ; -)
Спасибо за помощь,
Тим