1
\$\begingroup\$

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: 'example1@example.com' }, 
{ user_id: 5, email: 'example5@example.com' }, 
{ user_id: 13, email: 'example13@example.com'}]

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

[
{department_id: 1, users: [{user_id: 1, email: 'example1@example.com'},
 {user_id: 5, email: 'example5@example.com'}]}, 
{department_id: 2, users: [{ user_id: 13, email: 'example13@example.com']

I am retrieving data from db using following codes

data =
  User
  .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 } }
  end

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}
end

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.
\$\endgroup\$
1
  • \$\begingroup\$ I changed title but I want to refactor code so it was part of title but now removed it. \$\endgroup\$ May 20 at 8:41
1
\$\begingroup\$

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}
  end
  { department_id: department_id, users: users }
end

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.

\$\endgroup\$
1
  • \$\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\$ May 24 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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