Lemme pencil you in: Using iCalendar and Rails to sync calendar events

posted in tutorials


If you’ve worked with calendars, then you know the frustration of having two systems not keep events in sync. There are essentially three levels to keeping events in sync. The first is integration with every email provider you wish to support. Not a light initiative. The second is to find a product which aggregates multiple providers into a single API interface. Better solution, but open your wallet. Lastly, build a lightweight system that relies on the iCalendar standard. This last option is the focus of the article. Throughout the remainder of this post, we’ll explore pushing an event to an external provider’s calendar and keeping it in sync across systems without writing a single API request or integration.

Introducing SimpleCov+ Action: A Github action for ensuring test coverage

posted in articles


Testing your code thoroughly is an important part of a well functioning and easy to change application. Lack of adequate test coverage can be frustrating when refactoring, upgrading, or tracking down a bug. I’ve always wanted a way to ensure that each file maintains a minimum test coverage and if not fail continuous integration checks. After much searching, I decided to go ahead and build my own. Introducing SimpleCov+ Action for use within your Github actions.

Simulating a select dropdown change in Jest

posted in today i learned


While building a mobile friendly tab component, I created a select dropdown that allowed the user to control the displayed content. This worked in tandem with the existing click the name of the tab setup. Testing a simple click event is trivial by using .click() but I quickly found that simulating a select dropdown change wasn’t as straightforward nor as documented. I stumbled on the following solution which hopefully helps someone else stuck.

How to test redirect_back_or_to

posted in today i learned


Have you ever successfully used redirect_back_or_to in your application only to find out that testing was a challenge? Both methods rely on browser history which is generally not available within controller test and request specs. Recently I ran into this and after digging in came up with a simple solution.

Tips I learned working with ActiveStorage

posted in today i learned


ActiveStorage is a great system for configuring your cloud file storage. It takes care of much of the details and allows you to focus on the most important parts: file upload and file download. Recently, I had the opportunity to work through an uploader on Rails 7 within the Administrate admin interface. Fun journey that left me with a couple tricks up my sleeve the next time I reach for ActiveStorage.

Automating Accessibility with Ruby and Axe Core

posted in tutorials


Building an accessible application can be challenging. Keeping an application accessible can be impossible. Without dedicated roles or full team support, accessibility regressions are easy to introduce.

In the past, I’ve used eslint-plugin-jsx-a11y for ensuring React components are accessible, and it helped tremendously. Recently, I’ve dived into Hotwire & Stimulus and needed a solution for ensuring an accessible application. Now as a disclaimer, all automated accessibility checkers have gaps between them and being fully accessible. Striving for a dedicated position or policy to ensure compliance is still something that automation can’t replace. That being said, automation can help keep regresssion at bay.

Examining power and privilege in the workplace; Basecamp's problematic policies

posted in articles


Before I go any further, I’d like to acknowledge my own privilege. I am white, cisgender, straight and male. My goal is to be an ally for oppressed communities and to support systemic change that addresses discrimination. My personal experience of discrimination is limited by my own privilege. I am open to learning from others whose personal experience may be different from my own and hearing other viewpoints.

I’ve been a fan of Basecamp for a long time. Recently, Basecamp made a decision to ban political and societal discussion in the workplace, along with disbanding their Diversity & Inclusion committee. These decisions have caused me to assess how I use Basecamp’s products and how I want to continue using them.

Using Hotwire to build a search form with minimal JavaScript

posted in tutorials


Hotwire is one of the slickest features to come to the development community. It comprises of Turbo, Stimulus, and Strada. It also brings many of the benefits of a single page application into a template rendering server environment.

I value the opportunity that this technology presents but have to acknowledge that it was created by Basecamp. You’ve likely read Basecamp’s recent decision to ban discussion of politics in the workplace along with disbanding their Diversity & Inclusion committee. My post is not an endorsement of these decisions. I’m planning to fully address their decision and how I think it impacts workplace inclusivity and company culture in a future post. The purpose of this post is to look at the new technology and I look forward to spending more time and thought reflecting on those decisions.

Add joy to your test suite with Cardi B

posted in articles


We’ve been in the pandemic now for nearly a full year. That’s enough time to make everyone feel a bit down and exhausted. Humor is a great way of coping with pandemic fatigue or you know just generally putting you in a good mood. What better way to encourage yourself than having Cardi B join you for testing your code.

Ordinal abbreviations for dates in Rails

posted in today i learned


Working with Dates and Times as a developer can be a tricky business. Recently I ran into an interesting time format which consisted of day of week, abbreviation of month, and the ordinalized day of the month. If you’re unfamiliar with ordinalized dates what it refers to are day of the month followed by a suffix. So 1st, 2nd, 3rd… I found a super cool trick to making this happen built into ActiveSupport::Inflector.

  • 1
  • 2
  • 3
  • 4
  • 5