Skip to main content

A Simple Solution for Combining Different Data Types in Rails

When building Humadroid’s dashboard, I needed to show both company announcements and employee shoutouts in a single feed. At first, I took what seemed like the easy route - using notifications as a bridge between these different types of content. Each announcement or shoutout would create a notification, and I’d just query those. Simple enough, right?

Well, not quite. I soon realized this approach had a major flaw: new users couldn’t see older announcements or shoutouts. They’d join the company and find an empty dashboard. Not exactly the welcoming experience I was aiming for!

Quick Tip: Reading Ruby Version from .tool-versions in Your Gemfile

While migrating from asdf to mise as my version manager, I needed to update how my Gemfiles read the Ruby version. It’s a small change, but I thought it might be useful to share.

With asdf, I was using .ruby-version:

ruby File.read(File.expand_path('.ruby-version', __dir__)).chomp

Now with mise using .tool-versions, which can contain versions for multiple languages, the line changed to:

ruby File.read(File.expand_path(".tool-versions"))[/^ruby[@ ](.+)$/, 1]

The regex matches a line starting with “ruby” (followed by either a space or @ symbol) and captures the version number.

A Simple Fix for Dynamicly Added External Widgets in Turbo-Enabled Sites

While working on Humadroid, I recently stumbled upon an interesting challenge with our chat widget. It’s a small discovery, but one that might save other developers some headaches.

The Problem

If you’re using Turbo (formerly Turbolinks) and external widgets like Chatwoot, you might notice they disappear or reload whenever you navigate between pages. This happens because these widgets usually attach themselves to the end of your DOM, and Turbo replaces all that content during page transitions.

This Week I've Learned - 2024-W49

PERSONAL

No post last weeks - had to take a break. Learning that rest is important, even when there’s lots to do.

TECH & CODING

WordPress Got Humadroid’s landing page rewritten in WordPress to let Bartek edit content without my help. Big thanks to Ilia and Florin from inntech who handled it. The frontend is super fast, but I was surprised how slow the admin side has become - making complex changes is really painful.

Nested forms with just Turbo Streams

Edit 11.12.2024: I’ve updated turbo stream responses to include field index.

Recently I was working on implementing dynamic nested forms using Turbo Streams, focusing on handling both new and persisted records without custom JavaScript. Well, mostly for fun, to try something new. And while there are multiple approaches to this problem, including Stimulus controllers or plain JavaScript, Turbo Streams offer a clean, server-driven solution that leverages Rails conventions.

The Core Concept: Form Manipulation vs Persistence

A key aspect of this implementation that might not be immediately obvious is that the IngredientsController doesn’t actually persist any data. Its sole responsibility is to manipulate the form structure through Turbo Stream responses.

This Week I've Learned - 2024-W44

CODING

  • Found a nice Ruby gem (actually it was recommended to me in this Xitter thread) - procore-oss/blueprinter which seems to be a very nice serializer (JSON Object Presenter) for Ruby. As I was implementing API for Humadroid recently with Time-To-Market in mind, I’ve actually settled on Grape & Grape Entity, but when we’ll be creating v2 of it in bigger team, we’ll most likely look for alternatives and blueprinter looks like a solid contender.

This Week I've Learned - 2024-W42

Trying to restart this blog, one thing at a time. For quite some time I wanted to start publishing some smaller blobs I find interesting, but giving each and everyone a post seemed wasteful. That’s why I’ve decided to publish my weekly learnings and findings - some links, some thoughts from development, some API methods I haven’t used before. Without further ado, here it is for the first time.

This week I’ve learned: