2

I find myself repeating this type of code over and over and over again.

<% if !@model.property.blank? %>
    <label>Property</label>
    <div><%= @model.property %></div>
<% end %>

The goal being to only output a label and a property value if and only if the value is present. I find that repeating this code many times makes it hard to scan the source code. Can this be reduced and made more concise? What pattern can be applied to this to make it easier to code?

Jeff
  • 13,943
  • 11
  • 55
  • 103

2 Answers2

3

You can create a helper for you, that will deal with theses tests automatically:

# application helper
def display_if_exists(instance, attribute)
  return nil if instance.blank? || attribute.blank?

  label_tag = content_tag :label do
    instance.class.human_attribute_name attribute.to_sym
  end

  div_tag = content_tag :div do
    instance.try(attribute.to_sym)
  end

  return (label_tag + div_tag).html_safe
end

And use it this way:

# view
display_if_exists(@user, :username)

A little improvement, with options:

def display_if_exists(instance, attribute, options = {})
  return nil if instance.blank? || attribute.blank?

  label_options = options.delete(:label)
  div_options = options.delete(:div)

  label_tag = content_tag :label, label_options do
    instance.class.human_attribute_name attribute.to_sym
  end

  div_tag = content_tag :div, div_options do
    instance.try(attribute.to_sym)
  end

  return (label_tag + div_tag).html_safe
end

And use the options like this:

display_if_exists(@user, :username, { label: { class: 'html-class' }, div: { style: 'margin-top: 2px;' } })

An other option is the Rails Presenter Pattern. It is very interesting, but might be too deep for what you are trying to achieve:

Community
  • 1
  • 1
MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • This is fantastic. The presenter pattern looks pretty interesting, but I think youre right in that it is a bit much for my current situation. – Jeff Apr 03 '14 at 19:15
0

May be you would like to extract this into a helper method where you can put the existing logic and call that helper.

def print_property_if_present(model)
  "<label>Property</label><div>#{model.property}</div>" if model.property.present?
end

Don't forget to call html_safe to render the output in an HTML printable format. Hope this helps!

Siddhant
  • 293
  • 1
  • 3
  • 8