Open source

My collection of Ruby gems 💎

I have a number of gems released (or planned to be).

This page shows the collection of Ruby gems, including examples of usage.

Typed Attributes: Runtime checked typed Attributes (based on ActiveModel)

Define instance attribute accessors with expected data type information, default values and coercion:

attr_string :tag, default: "div", convert: true
attr_string :label, allow_nil: false
attr_symbol :variant, default: :contained, in: [:contained, :raised, :outlined, :text]
attr_array :scores, sub_type: Numeric, convert: true

VC: View Components for Rails

Sound familiar? In 2018, before the release of Joel Hawksley’s view_component I built my own ViewComponent implementation. Over the course of the next 2 years it evolved and grew to be very feature complete.

While I now highly recommend view_component you might be interested to compare with what I have here.

Renamed as VC: encapsulating views into testable, reusable entities that play nicely with the Rail additionally with:

  • attributes or ‘props’ of views can be validated and have their types checked
  • DSL is provided for working with Stimulus
  • RSpec shared examples and support for fuzz testing view components
  • play nicely with the Rails Russian doll view caching mechanism

Example Component

class Avatar < ::VC
  attr_string :image_url
  attr_string :initials

  validates_length_of :initials, minimum: 1, maximum: 3, allow_blank: true

  attr_symbol :shape, in: [:circle, :square], default: :circle
  attr_symbol :size, in: [:tiny, :small, :medium, :large, :extra_large], default: :medium

  def element_classes
<%= view_component_tag component do %>
  <% if component.image_url? %>
    <%= image_tag component.image_url %>
  <% else %>
    <p><%= component.initials %></p>
  <% end %>
<% end %>

Testing a Component

RSpec.describe ::Avatar, type: :view do
  # Check each parameter combination
    "a view component",
    attributes: {
      image_url: {
        valid: ["", nil],
        invalid: ["not_a_valid_asset"]
      initialsZ: {
        valid: ["A", "AB", "A B"],
        invalid: ["AB C", 123]

  # Checks the specific component instance will render
    "a rendered view component",
    component: "A B", url: "http://image_url"),
    content_to_match: %r{src="http:\/\/image_url},

  # More custom render tests
  describe "#render" do
    it "does not render successfully with invalid initials length" do
      expect { "AB C").render(view_context: view)
      }.to raise_error ActiveModel::ValidationError

What is next?

For each of these gems I plan to write a post about them and discuss how they might be useful while they compare to alternatives out there.

I also plan to do some deep dives into the how’s and whys of some of the limitations for both these gems and alternatives.

« PIC programming with JAL
Looking forward to 2021 🚀 »

Read more • open-source Ruby