将 ActiveRecord::Relation 按字段分组到带有字典的哈希中

Wal*_*ker 2 activerecord ruby-on-rails

我正在运行一个ActiveRecord返回一堆记录的查询。

让我们以此为例

ad_account    campaign_id    impressions
1             1              500
1             2              8,800    
1             3              6,000
2             7              900
2             9              9,324
Run Code Online (Sandbox Code Playgroud)

如何将这些结果转换为包含按 ad_account 分组的数组的哈希值?

所以我想要这个

{"1"=>[{ad_account: 1, campaign_id: 1, impressions: 500}, {ad_account: 1, campaign_id: 2, impressions: 8,800}, {ad_account: 1, campaign_id: 3, impressions: 6,000}], 

"2"=>[{ad_account: 2, campaign_id: 7, impressions: 900}, {ad_account: 2, campaign_id: 9, impressions: 9324}]}
Run Code Online (Sandbox Code Playgroud)

所以基本上每个ad_account都是键,值是所有字段的数组。

我该怎么做呢?

我已经尝试过,但它不起作用,因为它只是覆盖

allCampaigns.each do |campaign| 

    hash[campaign.ad_account] = campaign 

end
Run Code Online (Sandbox Code Playgroud)

Sim*_*ime 8

您可以用于group_by此用途。例如:

Ad.all.group_by(&:ad_account)
# => { 1 => [#<Ad id: 1, ad_account: 1, campaign_id: 1, impressions: 500>,
#            #<Ad id: 2, ad_account: 1, campaign_id: 2, impressions: 8800>,
#            #<Ad id: 3, ad_account: 1, campaign_id: 3, impressions: 6000>],
#      2 => [#<Ad id: 4, ad_account: 2, campaign_id: 7, impressions: 900>,
#            #<Ad id: 5, ad_account: 2, campaign_id: 9, impressions: 9824>]}
Run Code Online (Sandbox Code Playgroud)

这作用于查询结果,作用于可枚举对象ActiveRecord::Relation,它不会GROUP BY向您的 sql 查询添加子句。

然后,如果您想要该哈希,具体而言,您可以添加serializable_hash

Ad.all.group_by(&:ad_account).transform_values do |ads|
  ads.map do |ad|
    ad.serializable_hash(only: ['ad_account', 'campaign_id', 'impressions'])
  end
end
# { 1 => [{"ad_account"=>1, "campaign_id"=>1, "impressions"=>500},
#         {"ad_account"=>1, "campaign_id"=>2, "impressions"=>8800},
#         {"ad_account"=>1, "campaign_id"=>3, "impressions"=>6000}],
#   2 => [{"ad_account"=>2, "campaign_id"=>7, "impressions"=>900},
#         {"ad_account"=>2, "campaign_id"=>9, "impressions"=>9824}]}
Run Code Online (Sandbox Code Playgroud)