ActiveRecord:有效计算总和

时间:2013-01-28 15:28:00

标签: ruby-on-rails ruby rails-activerecord

我想显示广告系列的分析。以下是一些背景信息:

  • 不同公司针对特定广告收集广告系列统计信息
  • 通常会为多个公司的同一广告生成统计信息
  • 统计信息收集在名为DailyStat
  • 的模型中
  • 每个广告系列都涉及许多可能收集或未收集统计信息的公司
  • 广告系列和公司通过广告系列进行关联

广告系列 - >广告 - > DailyStat

DailyStats同时属于广告和公司,具体取决于哪家公司生成统计信息。

模型如下:

class DailyStat < ActiveRecord::Base
  attr_accessible :ad, :clicks, :company, :date, :impressions

  belongs_to :ad
  belongs_to :company
end

class Ad < ActiveRecord::Base  
  belongs_to :campaign
  has_many :daily_stats
end

class Campaign < ActiveRecord::Base
  has_many :campaignizations, :dependent => :destroy
  has_many :companies, :through => :campaignizations

  has_many :ads, :dependent => :destroy
end

class Company < ActiveRecord::Base

  has_many :campaignizations, :dependent => :destroy
  has_many :campaigns, :through => :campaignizations

end

现在,我最想做的是:

  • 检索特定广告系列的展示摘要(按公司划分)
  • 检索特定广告系列(按公司)
  • 的每个广告的展示摘要

作为ActiveRecord的新手,我尝试过使用包含,总结等等,但似乎无法解决如何从广告系列到公司分组统计数据(没有迭代所有广告)。

我的问题:

  1. 解决这个问题的有效方法是什么?
  2. 对DailyStats进行非规范化和添加广告系列信息是否有意义?

1 个答案:

答案 0 :(得分:1)

可以用arel / AR实现复杂的聚合计算,虽然有点复杂......这里有一个例子(不确定它是否有效,但是你得到了精神):

检索特定广告系列的展示摘要(按公司):

DailyStat
  .joins(  company: {campaignizations: :campaign} )
  .where(  Campaign.arel_table[:id].eq arbitrary_id )
  .group(  DailyStat.arel_table[:company_id] )
  .select([ 
             DailyStat.arel_table[:impressions].sum, 
             DailyStat.arel_table[:company_id] 
          ])

正如我所说,我不知道这是否有效 - 当使用组+选择AND对象实例时,你可能会遇到很多意想不到的问题(不要忘记AR为每个实例化DailyStat对象返回行,无论它是否有意义),所以你最好坚持使用select_all原始SQL /纯Arel。

如果您的RDBMS允许,另一个需要考虑的选择是使用DB View。通过一些黑客攻击,可以使用AR模型访问数据库视图,就好像它是一个表格......这可能会非常有用。