How would you refactor this case statement? I've got this code in my ApplicationHelper file:

def new_button
  case controller_name
  when 'cars'
    "&lt;li class='has-form'&gt;&lt;a class='button' href='#{new_car_path}'&gt;New Car&lt;/a&gt;&lt;/li&gt;".html_safe
  when 'trucks'
    "&lt;li class='has-form'&gt;&lt;a class='button' href='#{new_truck_path}'&gt;New Truck&lt;/a&gt;&lt;/li&gt;".html_safe
  when 'mopeds'
    "&lt;li class='has-form'&gt;&lt;a class='button' href='#{new_moped_path}'&gt;New Moped&lt;/a&gt;&lt;/li&gt;".html_safe
  else
    nil
  end
end


So I can just put &lt;%= new_button %&gt; in the view, to display the appropriate button based on the controller_name being accessed.

I have about 10 different controllers to select from (and I'm sure that collection will grow), so the code is getting a bit lengthy.

Is there a better way to accomplish this?
I haven't run this code, but maybe something along these lines:

def new_button
  content_tag(:li, class: "has-form") do
    text = "New #{controller_name.singularize.titleize}"
    path = { controller: controller_name, action: "new" }
    link_to(text, path, class: "button")
  end
end


Using content_tag and link_to is arguably cleaner, and they handle escaping automatically.

Letting the router generate the URL for you from a hash is preferable to doing string manipulation.

The text generation is perhaps inelegant, but simple. If you're using I18n elsewhere in this app I'd consider using that:

model_slug = controller_name.singularize
text = t("new_x", x: t("activerecord.models.#{model_slug}"))


But it's overkill if you're not using it for anything else.