I write about web design & development, particularly on topics like Ruby on Rails, Hotwire, and Tailwind.

Don’t want to miss a new post? Sign up for the monthly studio newsletter.


March 12, 2022

Adding Meta Tags to a Rails CMS with Polymorphism

There are pros and cons to building CMS functionality into your Rails app. It can be easy to forget important aspects, like SEO and Open Graph. Here's an approach to addressing both using polymorphism and the MetaTags gem.

January 20, 2022

Time Tracking for Freelance Developers

Time tracking is terribly mundane. But if you charge by the hour, or need to account for how you spend your work day, it's absolutely essential.


November 22, 2021

Audit Logging in Rails

Need to add audit logging to your Rails application? In this post, I review five popular Ruby gems you can use, walk through rolling your own solution, and share some recommendations about what solution to choose.

November 12, 2021

Full Text Search in Postgres with View-Backed Models in Rails

Here's a fast way to add full text search across multiple AR models using the PgSearch and Scenic gems, while also surfacing a distinct domain concept in your Rails application.

November 01, 2021

GitHub Issue-style File Uploader Using Stimulus and Active Storage

I recently built a drag-and-drop and copy-and-paste file uploader for Markdown (like GitHub’s editor) using Stimulus and Active Storage. Check out the code and my write up on it.

October 19, 2021

Migrating from Webpacker to the New Bundling Approach

You may have heard that Rails 7 will have three great answers to Javascript in 2021. Well, you don’t have to wait until Rails 7 is released to switch from webpacker to the new, simpler bundling approach, using jsbundling-rails and cssbundling-rails.


May 05, 2017

Managing Sidekiq Processes with Upstart

I normally use resque for background jobs in Rails (with capistrano-resque for managing resque processes). But I decided to switch to Sidekiq on a new application. I spent some time familiarizing myself with the best practices and came across this post by Mike Perham, Sidekiq's author. The best and most...

April 25, 2017

Better SQL in Ruby with the sql_query gem

I've been writing a lot of SQL lately, as evidenced by my last couple posts. I was working on a particularly long query the other day when I thought, "it would be nice I could write SQL using partials to manage duplicated logic." One quick Google search confirmed I was...

April 01, 2017

Returning The Greater of Two Date Fields, Where Either Could Be NULL

In keeping with SQL tricks I wrote about a few days ago, here's another technique that I've found useful recently. Let's say you want to return the greater of two date fields in your result set. If you know that both fields will contain a date, then you can simply...

March 28, 2017

Handy SQL Functions For Self-Referencing Tables

I have a client that uses NetSuite, a cloud-based CRM/ERP system. NetSuite records customer information in a datbase table called (surprise!) . The table is self-referencing, so you can have with many by setting the on the subcustomer records to the on the customer record. When we originally set up...

March 18, 2017

Five Types of Internal Documentation Needed for Software Teams

As I see it, there are five types of internal documentation needed for software teams. (Often, a software team will produce external documentation for their end users, in the form of a help section, user guides, or a searchable knowledge base. But the following are categories of documentation I see...

March 10, 2017

Using the Dentaku Gem to Manage Business Policies Outside of Your Codebase

I was reading The Pragmatic Programmer recently, and was struck by something I hadn't considered before. Be sure not to confuse requirements that are fixed, inviolate laws with those that are merely policies that might change with a new management regime. That's why we use the term semantic invariants—it must...

March 08, 2017

Client Collaboration

Professional web design is always collaborative. Even if you are the sole designer or developer on a project, you are in collaboration with your client. What you create together will always be constrained in some ways by your client, as it will also be constrained by you. I fought this...

February 24, 2017

Making Static Sites Dynamic...Somewhat

I'm kind of in love with static site generators (Middleman in particular). For marketing and informational sites that don't change very often, I get many of the benefits of my normal Rails framework development and deployment toolset, with a simpler, faster, and more secure final product. (It's just hard to...

February 22, 2017

A Reusable SJR Approach in Rails

I was recently working on a Rails client project where certain pages needed to display various record types and each collection of records needed to be listed on the page, and needed to be editable in-place. So for example, let's say a company had associated contacts, products, and locations. On...

February 14, 2017

Managing Redirects in Middleman

If you need to maintain redirects for old pages in a Middleman site, you can do so by adding something like this to your config file: If you've only got a few redirects, this isn't too bad. But if you have dozens or hundreds, all those redirect calls makes reading...

February 08, 2017

Table of Contents Helper for Markdown in Middleman

For pages on your site with a lot of content, it can be nice to have sidebar navigation with a Table of Contents for the page. If you're using Middleman with Markdown content, here's a way you can do that. 1. Use the redcarpet gem to render Markdown for your...

January 16, 2017

DRYing up Nginx configurations

I have a web server that hosts quite a few Middleman sites via Nginx. Since the sites are very similar, their Nginx configuration is largely the same. I recently moved common configurations into a separate include file, which has made it easier to understand the differences between site configuration files,...

January 13, 2017

Poor man’s inbound email processing in Rails with the Mail gem and Gmail

Most Rails developers seem to be using transactional email services to handle their inbound email processing needs these days. See services like Postmark, SendGrid, and Mandrill, which can all send webhook requests to your application whenever an email is received. But what if you're on a limited budget, or can't...


December 09, 2015

Custom currency input for Simple Form

Today, I was moving a standard Rails form to <a href="">Simple Form</a> and realized that one of the form inputs is actually a Bootstrap <a href="">input group</a>, with an add-on at the beginning of the input field with the proper currency symbol. There’s no built-in way to replicate this with...

December 03, 2015

How to mark optional form fields with Simple Form

<a href="">Simple Form</a> is a powerful gem for creating forms in Rails. For instance, Simple Form can look at your form object and display fields as “required” if they have validations on them, rather than you hard-coding that in the markup. By default, Simple Form will prepend required field labels...

May 20, 2015

Auto-generate navigation from page headers in Middleman

I’m working on a Middleman site right now that has one long page of content with a sidebar of navigation that links to the headers and sub-headers found on the page. (Underscore.js is a good example of this.) This is a common style for technical documentation sites these days. I...

May 04, 2015

A simple interface for the controller context in your Rails app

Oftentimes in a Rails app, you namespace your controllers based on the context. will namespace all your admin controllers, may namespace all the controllers in your members-only area. Have you ever needed to know the namespace context in your layout? Here’s a simple interface you can use: First, drop the...

March 11, 2015

How to add High Voltage static pages to your sitemap file

<a href="">High Voltage</a> is a fantastic gem for adding static pages to your Rails app. I’m using it extensively on a project that has a large number of static, style-heavy pages that don’t make sense to serve from the database. The other day my client asked me to add a...

February 12, 2015

Active Record enum form select

I’ve been enjoying the new <a href="">Active Record enums</a> in Rails 4.1. But I haven’t found a nice way to represent the enum options in a form select. So, I wrote a couple small helper methods that I put in application_helper.rb: ``` def optionsfromenumforselect(instance, enum) optionsforselect(enum_collection(instance, enum), instance.send(enum)) end def...


September 09, 2014

Get a word count from your Rails app views

I needed a way to calculate the number of words in a Rails application’s views, to estimate the cost of translating the content to another language. Pass this script the path to your views directory (or a subdirectory) to get a word count. ``` !/usr/bin/env ruby require "action_view" require "fileutils"...

September 05, 2014

A Tumblr Theme Development Workflow

This site has been running on Tumblr for a while now and, while I love using Tumblr for posting content, I’ve found theme development to be frustrating and tedious, particularly with trying to manage asset files. I’m used to single-command site deployment, so going back to copy-and-paste and manual file...

July 19, 2014

Simple Site-wide Announcements in Rails

I recently needed the ability to post site-wide announcements on a multi-tenant Rails application I work on, to announce scheduled downtime. Most solutions I’ve seen call for the creation of an announcements model and database table. It seemed a bit much to be querying an announcements table with every page...

January 24, 2014

Devise & CAS, using devise_cas_authenticatable and CASino

I work on a multi-tenant Rails application that serves four different sites (,,, from a single instance. The user accounts are not constrained to a single site, so a user can log in to any one of the sites with the same credentials. The business owners asked...


December 04, 2013

Rails AJAX Forms & Geocoding with Google

If you’ve done geocoding using Google’s APIs lately, you know that the best practice nowadays is to geocode on the client side and pass your latitude/longitude coordinates to the server, rather than having the server make the geocode request. Google caps the number of geocode requests based on IP to...

January 25, 2013

Setting up multiple instances of Redis on a Mac

I'm using Redis on a project and couldn't find a good guide for setting up multiple instances on a Mac. So, I decided to write up how I did it. (You might want this if you need one instance for development and a separate instance for running your test suite.)...


November 02, 2011

Pow Awesomeness for PHP & Static Sites

I recently started using Pow for my Rails apps in development. Pow is a "zero-config Rack server for Mac OS X" that makes it a cinch to access your Rails apps by individual host name and without having to futz with /etc/hosts or funky ports. Just create a quick symlink...