简体   繁体   中英

How can I make this method more concise?

I get a warning when running reek on a Rails project:

[36]:ArborReloaded::UserStoryService#destroy_stories has approx 8 statements (TooManyStatements)

Here's the method:

def destroy_stories(project_id, user_stories)
  errors = []
  @project = Project.find(project_id)
  user_stories.each do |current_user_story_id|
    unless @project.user_stories.find(current_user_story_id).destroy
      errors.push("Error destroying user_story: #{current_user_story_id}")
    end
  end
  if errors.compact.length == 0
    @common_response.success = true
  else
    @common_response.success = false
    @common_response.errors = errors
  end
  @common_response
end

How can this method be minimized?

First, I find that class and method size are useful for finding code that might need refactoring, but sometimes you really do need a long class or method. And there is always a way to make your code shorter to get around such limits, but that might make it less readable. So I disable that type of inspection when using static analysis tools.

Also, it's unclear to me why you'd expect to have an error when deleting a story, or who benefits from an error message that just includes the ID and nothing about what error occurred.

That said, I'd write that method like this, to reduce the explicit local state and to better separate concerns:

def destroy_stories(project_id, story_ids)
  project = Project.find(project_id) # I don't see a need for an instance variable
  errors = story_ids.
    select { |story_id| !project.user_stories.find(story_id).destroy }.
    map { |story_id| "Error destroying user_story: #{story_id}" }
  respond errors
end

# Lots of services probably need to do this, so it can go in a superclass.
# Even better, move it to @common_response's class.
def respond(errors)
  # It would be best to move this behavior to @common_response.
  @common_response.success = errors.any?
  # Hopefully this works even when errors == []. If not, fix your framework.
  @common_response.errors = errors
  @common_response
end

You can see how taking some care in your framework can save a lot of noise in your components.

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