I have wrote following solution for one answer but I want to refactor to make it more simple and readable.

I am receiving params

sample_params = [{ user_id: 1, email: '[email protected]' }, 
{ user_id: 5, email: '[email protected]' }, 
{ user_id: 13, email: '[email protected]'}]

I want to create following hash to replace emails received from params

{department_id: 1, users: [{user_id: 1, email: '[email protected]'},
 {user_id: 5, email: '[email protected]'}]}, 
{department_id: 2, users: [{ user_id: 13, email: '[email protected]']

I am retrieving data from db using following codes

data =
  .where(id: sample_params.pluck(:user_id))
  .pluck(:department_id, :id)
  .group_by(&:first).map do |department_id, users|
    { department_id: department_id,
      users: users.map { |_, id| id } }

and then I am creating hash using following

result = []
data.each do |department|
  department_users = []
   department[:users].each do |user|
     emails = sample_params.select { |user| user[:user_id] == 1 }[0][:email];
     department_users << { id: user, emails: emails }
   end; result << {department_id: department[:department_id], users: department_users}

How can I refactor to get following benefits

  • Easy to read
  • less number of lines
  • Performance: It has one query of sql so not an issue but on memory I am saving all in array.
  • \$\begingroup\$ I changed title but I want to refactor code so it was part of title but now removed it. \$\endgroup\$ Commented May 20, 2021 at 8:41

1 Answer 1


Not sure if it's what you're looking for, in terms of readability:

data = User.where(id: sample_params.pluck(:user_id))
           .pluck(:department_id, :id).group_by {|u| u.shift }

results = data.map do |department_id, user_ids|
  users = user_ids.flatten.map do |id| 
    email = sample_params.find { |user| user[:user_id] == id }[:email]
    {user_id: id, email: email}
  { department_id: department_id, users: users }

About saving memory because of the array, there will be always the queried data to the db in memory, besides this new array you're generating. The garbage collector won't take care of all these until your http request has been finished, so I'm not sure if there's something here you can do to improve the use of space.
If this is the case where there are thousands of users mapped to this json, maybe you should consider to use .find_each, maybe caching data or another approach, but only you know what's the nature of the data you're querying.

  • \$\begingroup\$ I think this enough as it already make little bit improvement and readability. You are right but we don't have much data it is in params so there would be mostly 10-20 users to be updated. Thank you. \$\endgroup\$ Commented May 24, 2021 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.