Reputation: 26192
I've got a model User which has id, name, surname, role_id, permission_id
Here is few user entries :
User => {:name => 'Bob', :surname => 'surnmae', :role_id => 1, :permission_id = 2}
User => {:name => 'Alice', :surname => 'strange', :role_id => 1, :permission_id = 3}
User => {:name => 'Ted', :surname => 'Teddy', :role_id => 2, :permission_id = 3}
Now I need to group them first by role_id
and then by permission_id
, here is what I mean :
Category.select([:name, :role_id, :permission_id]).group_by(&:role_id)
Produces :
{1 =>
[#<User name: "Bob", role_id: 1, permission_id: 2>,
#<User name: "Alice", role_id: 1, permission_id: 3>]
2 => [#<User name: "Ted", role_id: 2, permission_id: 3>]
}
Which is close enough but I need them grouped with permission_id as well so it would look like this :
{:role_id => {:permision_id => [Array of users grouped by this criteria]}
}
Upvotes: 0
Views: 110
Reputation: 972
It is bit more tricky than it seems. It is better to write it into multiple steps. However, the following one-liner will work:
Hash[ User.all.group_by(&:role_id).collect{|role, grp| [role, grp.group_by(&:permission_id)]} ]
Output will be the following (which is probably what you are looking for):
{1=>
{2=>[{:name=>"Bob", :surname=>"surnmae", :role_id=>1, :permission_id=>2}],
3=>[{:name=>"Alice", :surname=>"strange", :role_id=>1, :permission_id=>3}]},
2=>{3=>[{:name=>"Ted", :surname=>"Teddy", :role_id=>2, :permission_id=>3}]}}
Same logic, but simpler to comprehend:
output={}
User.all.group_by(&:role_id).each{|role, grp| output[role]= grp.group_by(&:permission_id)}
# output has required goruping
Upvotes: 1
Reputation: 2780
Category.select([:name, :role_id, :permission_id]).group_by { |category| [category.role_id, category.permission_id] }
Edit: Nevermind, this doesn't provide quite the formatting you're looking for.
Upvotes: 0
Reputation: 66711
maybe something like
Category.select([:name, :role_id, :permission_id]).group_by(&:role_id).map{|role| role.group_by(&:permission_id)}
Upvotes: 1