问题
I have Order and Item models joined by OrderItem:
class OrderItem < ActiveRecord::Base
belongs_to :order
belongs_to :item
This query finds the IDs of the most popular items:
OrderItem.group(:item_id).order("count_id DESC").count("id").first(10).map(&:first)
This works, but what is count_id? Why does this work? What is going on here behind the scenes with order("count_id...?
回答1:
count_id is an alias that Rails gives to the SQL aggregate function COUNT("order_items"."id").
OrderItem.group(:item_id).count(:id) counts the number of rows for each individual item:
SELECT COUNT("order_items"."id") AS count_id, item_id AS item_id FROM "order_items" GROUP BY item_id
The magic behind the count_id part is in ActiveRecord::Calculations. The alias is determined here:
aggregate_alias = column_alias_for([operation, column_name].join(' '))
And the method comments for column_alias_for list show this example:
# column_alias_for("count", "id") # => "count_id"
After that, order lists the Item occurrences from largest to smallest. The return value will be a hash where the keys are Item IDs and the values are the count of occurrences.
first grabs the 10 items with the most occurrences, and map pulls out the item_id values.
来源:https://stackoverflow.com/questions/28683567/activerecord-group-and-count-where-does-count-id-come-from