简体   繁体   中英

cyclomatic complexity is too high rubocop for method

This is code I have using in my project. Please suggest some optimizations (I have refactored this code a lot but I can't think of any progress further to optimize it )

 def convert_uuid_to_emails(user_payload)
    return unless (user_payload[:target] == 'ticket' or user_payload[:target] == 'change')
    action_data = user_payload[:actions]
    action_data.each do |data|
      is_add_project = data[:name] == 'add_fr_project'
      is_task = data[:name] == 'add_fr_task'
      next unless (is_add_project or is_task)
      has_reporter_uuid = is_task && Va::Action::USER_TYPES.exclude?(data[:reporter_uuid])
      user_uuids = data[:user_uuids] || []
      user_uuids << data[:owner_uuid] if Va::Action::USER_TYPES.exclude?(data[:owner_uuid])
      user_uuids << data[:reporter_uuid] if has_reporter_uuid
      users_data = current_account.authorizations.includes(:user).where(uid: user_uuids).each_with_object({}) { |a, o| o[a.uid] = {uuid: a.uid, user_id: a.user.id, user_name: a.user.name} }
      if Va::Action::USER_TYPES.include? data[:owner_uuid]
        data['owner_details'] = {}
      else
        data['owner_details'] = users_data[data[:owner_uuid]]
        users_data.delete(data[:owner_uuid])
      end
      data['reporter_details'] = has_reporter_uuid ? users_data[data[:reporter_uuid]] : {}
      data['user_details'] = users_data.values
    end
  end

Note that Rubocop is complaining that your code is too hard to understand, not that it won't work correctly. The method is called convert_uuid_to_emails , but it doesn't just do that:

  1. validates payload is one of two types
  2. filters the items in the payload by two other types
  3. determines the presence of various user roles in the input
  4. shove all the found user UUIDs into an array
  5. convert the UUIDs into users by looking them up
  6. find them again in the array to enrich the various types of user details in the payload

This comes down to a big violation of the SRP (single responsibility principle), not to mention that it is a method that might surprise the caller with its unexpected list of side effects.

Obviously, all of these steps still need to be done, just not all in the same method.

Consider breaking these steps out into separate methods that you can compose into an enrich_payload_data method that works at a higher level of abstraction, keeping the details of how each part works local to each method. I would probably create a method that takes a UUID and converts it to a user, which can be called each time you need to look up a UUID to get the user details, as this doesn't appear to be role-specific.

The booleans is_task , is_add_project , and has_reporter_uuid are just intermediate variables that clutter up the code, and you probably won't need them if you break it down into smaller methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM