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
  auto_cache(true)
  
  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
    [
      "vc-avatar",
      "vc-avatar--#{shape}",
      "vc-avatar--#{shape}--#{size}"
    ]
  end
end
<%= 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
  it_behaves_like(
    "a view component",
    attributes: {
      image_url: {
        valid: ["https://cataas.com/cat/says/hello", nil],
        invalid: ["not_a_valid_asset"]
      },
      initialsZ: {
        valid: ["A", "AB", "A B"],
        invalid: ["AB C", 123]
      }
    },
  )

  # Checks the specific component instance will render
  it_behaves_like(
    "a rendered view component",
    component: described_class.new(initials: "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 {
        described_class.new(initials: "AB C").render(view_context: view)
      }.to raise_error ActiveModel::ValidationError
    end
  end
end

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.

Are you interested?

  • Interested in anything you read about above and want to be kept in the loop?
  • Want to read articles about Ruby & gems?
  • Want to learn about working as a freelancer or in a collective in tech?

Subscribe to my low-traffic, low-noise mailing list and I promise to keep things relavent!

Join the Newsletter

Subscribe to get our latest content by email.
    We won't send you spam. Unsubscribe at any time.

    « PIC programming with JAL
    Looking forward to 2021 ๐Ÿš€ »

    Read more • open-source Ruby