How to refactor assignments to satisfy Rubocop?

127 views Asked by At

I am assigning some values to an newly created (Icalendar-) Object:

def map_to_cal_event
    e             = Icalendar::Event.new
    e.dtstart     = to_icaldate start.to_datetime
    e.dtend       = to_icaldate self.end.to_datetime if self.end.present?
    e.summary     = title
    e.description = description
    e.url         = timetable_url
    e.categories  = categories
    e.location    = location

    e
  end

Using Rubocop it is complaining about
Metrics/AbcSize: Assignment Branch Condition size for map_to_cal_event is too high. [<8, 21, 1> 22.49/17]

It seems a very common assigment to me.
So, How to refactor this method to satisfy rubocop? Or should i put it in the ignore-list?

2

There are 2 answers

3
Yakov On BEST ANSWER

This should satisfy Rubocop, define a new event in a separate method using the tap method with a block then pass another block to it with all the assignments.


def map_to_cal_event
  build_new_cal_event do |e|
    e.dtstart     = dtstart
    e.dtend       = dtend
    e.summary     = title
    e.description = description
    e.url         = timetable_url
    e.categories  = categories
    e.location    = location
  end
end

def build_new_cal_event(&block)
  Icalendar::Event.new.tap(&block)
end

def dtstart
  to_icaldate(start.to_datetime)
end

def dtend
  to_icaldate(self.end.to_datetime) if self.end.present?
end
1
Benjamin Scharbau On

I've not done optimizing ABC metrics yet, but one thing that I would try here just by looking at the code is replacing the functions for dtstart and dtend by a helper function by itself, i.e.

def map_to_cal_event
  e             = Icalendar::Event.new
  e.dtstart     = dtstart_time
  e.dtend       = dtend_time
  e.summary     = title
  e.description = description
  e.url         = timetable_url
  e.categories  = categories
  e.location    = location

  e
end

def dtstart_time
  to_icaldate start.to_datetime
end

def dtend_time
  to_icaldate self.end.to_datetime if self.end.present?
end

(Posted as an answer instead as a comment to be able to format the code)