Flexible UI elements with Rails render blocks

Written on August 22, 2018

For the past few weeks I’ve been doing a lot of work in the web-application, Ruby on Rails. This is because Pathos Ethos, the agency I work for, is a Rails shop.

I’ve been finding developing in Ruby on Rails to be a delight. While I’ve developed in Ruby on Rails in the past, the scope of the projects that I’ve used it for were tiny compared to the projects I work in these days at Pathos Ethos.

One of the things I’ve been really digging these days is the Ruby templating system, ERB or Embedded Ruby. While it’s not a shiny, new UI framework like Vue.js, you can do some neat UI things with it.

Recently I was faced with a UI design problem and was able to solve it using Rails’ render helper.

The problem

Razzle dazzle edition

A pricing block that has a different button based on different contexts. Above is when the user doesn’t have the Razzle Dazzle Edition and wants the user to purchase it.

Current edition

When the user has purchased Razzle Dazzle Edition, the button now indicates the user currently has that as their current package.

Initially I knew I’d use a partial so that the same file could be used to render the pricing block in multiple places. The challenge was keeping the copy above and below the button the same while allowing for the button to change.

First pass

// purchase.html.erb
<div class="PricingBlock RazzleDazzlePricingBlock text-center">
  <%= render 'purchase/razzle_dazzle' %>
  <a href="#" class="Button OutlineButton">Get Razzle Dazzle</a>
  <p>Razzle Dazzle is the bees knees :bee:</p>
</div>

// _razzle_dazzle.html.erb
<h2>Razzle Dazzle Edition</h2>
<ul class="list-reset">
  <li>20% more shine than Base Dazzle</li>
  <li>Levels up your high-fiving skills</li>
  <li>Large size pizza included with every purchase</li>
</ul>

My initial pass at the problem, I moved the heading and the list into a partial which left the button to be changed based on context. But this didn’t seem like a great solution. The style for the actual UI block was handled outside of the partial and if there was a need to change the line underneath the block, I would have to change it in every place where it was called.

The solution

I then thought about whether I could pass parameters into the partial from the render helper and have everything including the button self-contained in the partial, but that didn’t seem to like an elegant approach. Then I remembered that the render helper can also be used in block form using do.

In using render as a block, I could move just about everything into the price block partial and pass it the different buttons based on context.

// purchase.html.erb
<%= render 'purchase/razzle_dazzle' do %>
  <a href="#" class="Button OutlineButton">Get Razzle Dazzle</a>
<% end %>

// _razzle_dazzle.html.erb
<div class="PricingBlock RazzleDazzlePricingBlock text-center">
  <h2>Razzle Dazzle Edition</h2>
  <ul class="list-reset">
    <li>20% more shine than Base Dazzle</li>
    <li>Levels up your high-fiving skills</li>
    <li>Large size pizza included with every purchase</li>
  </ul>
  <%= yield %>
  <p>Razzle Dazzle is the bees knees :bee:</p>
</div>

Now the price block is modularized into a single partial and making changes can be done in one place and it’ll apply to all areas where the partial is called.

Stay in touch

Thanks for reading this article. I'd love to stay in touch and share more tips on programming and side projects with you. Sign up and I'll send you my articles straight to your email, you'll also get a free copy of the light themed version of my Git cheat sheet.
Git cheat sheet preview image