Rails Image Helper

Often times when developing application, there are times that a developer may need to include logic to conditionally render UI elements. For instance, maybe an active CSS class in the navbar menu-item for the current page. Sometimes the required logic is more complex. In my case I needed to provide a fallback image when an image was not available from the API. In this article I will show the methodology I used to create a Rails Helper to meet this goal.

Structure

On my side project Your Congress, I am using a free GitHub repository, UnitedStates/Images which stores all the photographs of serving Congress members. The images are accessible through an API served from GitHub pages, by images size and member ID. So, the image URL will be configured like so: https://theunitedstates.io/images/congress/[size]/[member_id].webp.

The image is rendered in the ERB partial:

image_tag "https://theunitedstates.io/images/congress/225x275/#{senator.member_id}.webp"

Problem

The existing code works fine, but as new members have been added to the US Congress, the available images are not currently available for the new members. When the image is not available, the browser developer console logs a 404 status code, and the UI displays a broken image, thereby breaking the card layout. So, there needs to be a better way to access these images, and check for availability.

The goals:

This is too much complexity for the ERB partial, so to DRY out this process we will create a Rails Helper.

Solution

What are helpers in Rails? A helper is a method that is (mostly) used in your Rails views to share reusable code. RubyGuides

We are creating a new helper in app/helpers called bio_image_helper.rb. The basic structure of the helper is to create a module and then within the module, a method we will call within our view. We are going to define the URI string in a variable and pass in the member_id in an argument called member. So the basic structure:

module BioImageHelper

  def bioimage_helper(member)
    img_url = "https://theunitedstates.io/images/congress/225x275/#{member}.webp"
    res = Net::HTTP.get_response(URI.parse(img_url.to_s))

    res.is_a?(Net::HTTPSuccess) ? img_url : 'backup.webp'
  end

end

Remember the second goal was to validate the success of the image response, and offer a fallback image. We will use two libraries to meet these objectives: net/http and uri. With these, we will store to a variable (res) the response object and parse the img_url string. Then use a Ruby ternary to check the response object for an HTTPSuccess, and use the image, or our fallback image.

require 'net/http'
require 'uri'

module BioImageHelper

  def bioimage_helper(member)
    img_url = "https://theunitedstates.io/images/congress/225x275/#{member}.webp"
    res = Net::HTTP.get_response(URI.parse(img_url.to_s))

    res.is_a?(Net::HTTPSuccess) ? img_url : 'backup.webp'
  end

end

So, the image_tag in the partial now is abstracted to:

image_tag bioimage_helper(senator.member_id)

Thanks

Special thanks to the users on the Ruby on Rails Discord Server who pointed me in the right direction, with feedback, and code review.

Also, the Stack Overflow discussion which helped the most.

Footer

This has been fun. Leave a comment or send me a DM on Twitter.

Shameless Plug: If you work at a great company and you are in the market for a Software Developer with a varied skill set and life experiences, send me a message on Twitter and check out my LinkedIn.