Using Rubocop, pretty much any case statement is caught by the Cyclomatic Complexity cop, often the Assignment Branch Condition and method length cops as well. To get around this, I've been refactoring code like this:
def preview
case object.panel_type
when "image"
asset_image_path(object.asset)
when "profile_block"
Profile.find(object.type_id).try(:full_name)
when "slider"
if object.options.present? && object.options["slides"].present?
Slide.find(object.options["slides"][0]).headline
else
"Empty"
end
when "menu"
Menu.find(object.type_id).try(:name)
else
clean_content.try(:truncate, (object.span * 4))
end
end
Into this:
def preview
if %w(image profile_block slider menu search_list).include?(object.panel_type)
send("#{object.panel_type}_preview")
else
clean_content.try(:truncate, (object.span * 4))
end
end
private
def image_preview
asset_image_path(object.asset)
end
def profile_block_preview
Profile.find(object.type_id).try(:full_name)
end
def slider_preview
if object.options.present? && object.options["slides"].present?
Slide.find(object.options["slides"][0]).headline
else
"Empty"
end
end
def menu_preview
Menu.find(object.type_id).try(:name)
end
def search_list_preview
GridPanel::SEARCH_TYPES.invert[object.type_id]
end
In general, I think dynamic method names can be a bit problematic for maintenance. One of the problems with legacy Rails code is finding all the usage of dynamic methods in a project when you have to add or remove things. But in this case, I think the names have consistency and a limited scope, so it doesn't seem like it would be difficult to maintain or update later. Is there are more conventional way to do this?