"Binning" 按属性记录:如何构造 ActiveRecord 调用?

"Binning" records by attributes: how to structure the ActiveRecord call?

我有一份报告:

create_table "reports", force: :cascade do |t|
  t.date "date"
  t.bigint "technology_id", null: false
  t.bigint "user_id", null: false
  t.bigint "contract_id", null: false
  t.integer "distributed"
  t.integer "checked"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "people"
  t.integer "reportable_id"
  t.string "reportable_type"
  t.integer "impact", default: 0
  t.bigint "plan_id"
  t.integer "year"
  t.integer "month"
end

我正在尝试创建一个如下所示的集合:

{ year: { month: [:id, :id, :id] } }

我一直在玩这个:

Report.select(:id, :year, :month).group(:year, :month, :id).order(year: :desc, month: :asc)

我实际上不希望 :id.group() 方法中(因为我想按 :year 然后按 :month 分组)但我得到非常常见的错误:

ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "reports.id" must appear in the GROUP BY clause or be used in an aggregate function

关于在不执行 N+1 查询的情况下创建此集合的任何建议?

我认为 SQL 不能比选择行和分配顺序更进一步。接下来是将其处理为正确的格式:

Report
  .select(:year, :month, :id)
  .order(year: :desc, month: :asc)
  .group_by(&:year)
  .transform_values do |reports|
    reports.group_by(&:month).transform_values do |month_reports|
      month_reports.map(&:id)
    end
  end