我有一个格式为
的ActiveRecord::Associations:CollectionProxy
#<DailyViewMetric article_id: xxxxxx, date: xxxxxxx, views: xxxxxx, visitors xxxxx,.....>
在变量metrics
中
article_id是一个外键,并且在表中重复(因为一篇文章可以连续几天有指标(即今天有15个视图,第二天有20个视图)。
我需要一种方法来循环这一点,并对其中一些指标应用不同的操作,例如获取每篇文章的最小日期,视图总数(= sum(views))。我尝试了metrics.map do |a|
和metrics.collect
,但总是得到ruby错误undefined method 'views'
例如,让我们使用以下简化的数据集
article_id date views
1 2014-01-01 10
2 2014-01-01 15
1 2014-01-02 20
2 2014-01-02 12
3 2014-01-02 6
应该在后面产生如下的新数组:
article_id date views
1 2014-01-01 30
2 2014-01-01 27
3 2014-01-02 6
可以看到,views变量保存了相应文章的视图之和,date变量是日期的最小值。我该怎么做呢?我也试过metrics.to_a
,但我仍然得到这个错误。
我试过DailyViewMetric.find_by_sql("SELECT article_id, sum(views) from daily_view_metrics where article_id in(SELECT id from articles where user_id=xxx) GROUP BY article_id")
,如果我在mysql控制台中执行查询,它工作得很好,并返回上面的第二个表。但是当我在rails控制台中运行它时,它给了我
[#<DailyViewMetric id: nil, article_id: 1089536>, #<DailyViewMetric id: nil, article_id: 1128849>, #<DailyViewMetric id: nil, article_id: 1141623>,
在SQL/ActiveRecord中完全可以做到这一点。最终要运行的查询是
SELECT article_id, min(date), sum(views)
FROM daily_value_metrics -- Or whatever your table is called
GROUP BY article_id
您可以使用以下命令与ActiveRecord一起运行:
table = DailyValueMetric.arel_table
results = DailyValueMetric.select(table[:article_id],
table[:date].minimum.as('date'),
table[:views].sum.as('views')).group(:article_id).to_a
# Calling to_a so I can call first for the example
results.first.date #=> date
results.first.views #=> views
results.first.article_id #=> Id
记录看起来像
[#<DailyViewMetric id: nil, article_id: 1089536>, ...]
因为SQL查询不返回结果集中的id列。这是因为ActiveRecord::Base#inspect
显示的是表上定义的列,而不是表列之外的返回值。Views和Date不一定会显示,除非有一个具有相同名称的列,但是如果您在模型实例上调用这些属性,您将能够获得值