【发布时间】:2011-04-25 18:27:16
【问题描述】:
我有一个小部件模型。 Widgets属于Store模型,属于Area模型,属于Company。在公司模型中,我需要找到所有相关的小部件。简单:
class Widget < ActiveRecord::Base
def self.in_company(company)
includes(:store => {:area => :company}).where(:companies => {:id => company.id})
end
end
这将生成这个漂亮的查询:
> Widget.in_company(Company.first).count
SQL (50.5ms) SELECT COUNT(DISTINCT "widgets"."id") FROM "widgets" LEFT OUTER JOIN "stores" ON "stores"."id" = "widgets"."store_id" LEFT OUTER JOIN "areas" ON "areas"."id" = "stores"."area_id" LEFT OUTER JOIN "companies" ON "companies"."id" = "areas"."company_id" WHERE "companies"."id" = 1
=> 15088
但是,我以后需要在更复杂的范围内使用这个范围。问题是 AR 通过选择单个字段来扩展查询,这在 PG 中失败,因为所选字段必须在 GROUP BY 子句或聚合函数中。
这里是更复杂的范围。
def self.sum_amount_chart_series(company, start_time)
orders_by_day = Widget.in_company(company).archived.not_void.
where(:print_datetime => start_time.beginning_of_day..Time.zone.now.end_of_day).
group(pg_print_date_group).
select("#{pg_print_date_group} as print_date, sum(amount) as total_amount")
end
def self.pg_print_date_group
"CAST((print_datetime + interval '#{tz_offset_hours} hours') AS date)"
end
这是它向 PG 抛出的选择:
> Widget.sum_amount_chart_series(Company.first, 1.day.ago)
SELECT "widgets"."id" AS t0_r0, "widgets"."user_id" AS t0_r1,<...BIG SNIP, YOU GET THE IDEA...> FROM "widgets" LEFT OUTER JOIN "stores" ON "stores"."id" = "widgets"."store_id" LEFT OUTER JOIN "areas" ON "areas"."id" = "stores"."area_id" LEFT OUTER JOIN "companies" ON "companies"."id" = "areas"."company_id" WHERE "companies"."id" = 1 AND "widgets"."archived" = 't' AND "widgets"."voided" = 'f' AND ("widgets"."print_datetime" BETWEEN '2011-04-24 00:00:00.000000' AND '2011-04-25 23:59:59.999999') GROUP BY CAST((print_datetime + interval '-7 hours') AS date)
产生此错误的原因:
PGError: 错误: 列 “widgets.id”必须出现在 GROUP BY 子句或用于 聚合函数第 1 行:SELECT "小部件"."id" AS t0_r0, "小部件"."user_id...
如何重写 Widget.in_company 范围,以便 AR 不会扩展选择查询以包含每个 Widget 模型字段?
【问题讨论】:
-
Rails 3 大概?我在 Rails3/Heroku 中有一个更简单的情况,我没有选择特定的列 - 所以它正在执行 select * 并得到了这个错误 - 通过添加特定的列选择来修复它 - 但你正在这样做.... :(跨度>
标签: ruby-on-rails postgresql activerecord