0

This is a 2 part question

A newbie to activerecord/Rails. Once I execute the below activerecord query, I get

results = A.joins(:b).group(:id, :status).count

this result, now I want to present the results using an entity by postprocessing the output from

{[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}

to

[{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ]

(In the expected output's second hash, I added action1 => 0 and action2 => 0, because 0 should be default value.)

How to achieve the above output? I am unsure if the output of the query can be presented without postprocessing itself. So far I tried

summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}

need to make changes to the above map-reduce code to get expected result.

The expected response should look like the below, hence I am focussing on post processing the output of the query.

[
 { 'id' => value
   'action1' => count,
   'action1' => count,
   'action1' => count
 },
 {
  # same structure as above
 }
]

I am trying to expose for example, only the id field in rails console but hitting the error

class klassEntity < Grape::Entity
  expose :id
end

When I tried

klassEntity.represent([{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ])

this failed with (Object doesn't support #inspect) What am i doing wrong?

Update

I got this working by constructing a list of arrays from current output of

summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}

and each array element contains a hash of symbols. This worked in rails console as well. I am wondering if there is an optimal way to get here.

MrKickass
  • 93
  • 1
  • 13

1 Answers1

0

Find here an option using just the standard library.

I'm using map but with object (Enumerator#with_object) where the object is a Hash#new with a block given to get an empty hash as value to call Hash#merge! on it:

summaries = {[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}

summaries.map.with_object(Hash.new {|h, k| h[k] = {}}){|(v, k), h| h[v.first].merge!({v.last => k})}

The result:

#=> {1=>{"action1"=>2, "action2"=>2, "action3"=>1}, 2=>{"action3"=>2}}
iGian
  • 11,023
  • 3
  • 21
  • 36