Shpigford
Shpigford

Reputation: 25338

How to group rows based on multiple fields?

I have a notifications table where I email out reports to people based on the frequency they've selected.

If an email address exists across multiple questions and has the same frequency...then I need to group them together so I can send one report for both questions.

[
   #<Notification id: 1, question_id: 58, email: "[email protected]", frequency: "daily">, 
   #<Notification id: 2, question_id: 25, email: "[email protected]", frequency: "daily">,
   #<Notification id: 3, question_id: 47, email: "[email protected]", frequency: "monthly">,
   #<Notification id: 3, question_id: 19, email: "[email protected]", frequency: "monthly">
] 

So in my example data, 3 reports would be sent:

I may not be explaining this very well, so let me know if something needs clarification.

Upvotes: 1

Views: 50

Answers (1)

MrYoshiji
MrYoshiji

Reputation: 54882

You can achieve this with a regular group_by:

@notifications = your_method_to_retrieve_notifications
@notifications = @noticications.group_by do |notif|
  notif.ferquency + ':' + notif.email
end

This will group your notifications like this:

@notifications = {
  'daily:[email protected]' => [<Notification id: 1>, #etc.],
  'monthly:[email protected]' => [# list of notifications],
  'monthly:[email protected]' => [# list of notif]
}

If you want only an array of list of notifications grouped by frequency & email, use the above method and add this:

@notifications = your_method_to_retrieve_notifications
@notifications = @noticications.group_by do |notif|
  notif.ferquency + ':' + notif.email
end.values
# returns Array of arrays like:
[
  [<Notification id: 1 frequency: "daily", email "[email protected]">,<Notification id: 2 frequency: "daily", email "[email protected]">],
  [<Notification id: 3 frequency: "daily", email "[email protected]">],
  [<Notification id: 4 frequency: "monthly", email "[email protected]">,<Notification id: 5 frequency: "monthly", email "[email protected]">],
]

Upvotes: 1

Related Questions