Skip to main content

· One min read

I have a global keyboard shortcut (⌥`) to mute my microphone on Zoom. I've done this several ways in the past but right now my solution is to send the mute keyboard shortcut (⌘⇧A) to the Zoom app via Keyboard Maestro.

Screenshot of Keyboard Maestro

Download Macro

Mute status in macOS Menubar

Using SwiftBar, I have a script which checks the mute status and displays it in my menubar. Screenshot of Swiftbar Zoom mute state icon Download Script

· 4 min read

When serving assets and attachments from Rails and ActiveStorage, a CDN is a great way to reduce load on your web server and speed up content delivery to your users.

Asset CDN

First, even if you're not using ActiveStorage, you'll want to set up a CDN to stand in front of your app. This will proxy requests for images, fonts, javascripts, and stylesheets that live in your app's repository.

The ideal setup here is to serve your assets from your app, set a high cache-expiration, and serve your assets through a CDN.

Setting up your Asset CDN

For a CDN, I recommend Amazon CloudFront. You'll want to create a web distribution which points at the root of your app. Heroku [has a good guide][2] on that.

· One min read

My main computer is my iMac. It seemed like every time I opened my MacBook Pro, it would show this screen:

MacBook Pro showing low battery full screen

So I researched a bit and fixed it. Here's what I did:

· 2 min read

I was looking for an outbound ping tool that I could run continuously on a secondary monitor or in the background so I could quickly troubleshoot internet outages or packet loss.

For example, when I'm in a video call, if the other person starts to have issues with audio/video, I can, with a glance, tell if it's me or not by looking for latency/packet loss amongst the hosts I'm pinging.

[ICMPUtil][1] is the best I've found. It's $6 [on the App Store][2].

Screenshot of ICMPUtil

· 2 min read

I've been searching for a solution to allow me to instantly search Google from anywhere on my Mac. My goal is to access the result I want as fast as possible.

My previous solution was to use the default fallback search in Alfred. I hit Option-Space typed my search and pressed Enter. This was pretty good. It would open Safari with my query's Google results. The page would take two seconds to load and then I'd have to figure out how to select the result I wanted.

Ideally, I'd just press 1, 2, 3, etc on my keyboard to launch the corresponding result. But the closest I could find was a vim-like browser plugin (such as Vimari) which gives all links a letter combination to type to navigate to it. Or Shortcat, which I use for navigating all macOS UI.1

This solution wasn't fast enough for me though. I wanted a more modal experience where I hop into an ephemeral search session.

· 2 min read

I wanted to log my internet's upload and download speeds over time. brew search speed turned up speedtest-cli which uses servers to measure what I was interested in.

Unfortunately it's a one time test and if you want it to repeat, you'll need to automate it. I chose a simple shell while loop to handle this for me1:

while; do
speedtest-cli --json --server $(
speedtest-cli --list |
grep -E "CenturyLink|Sprint|Enid|OneNet|Cox|Suddenlink" |
head -20 |
cut -f 1 -d ')' |
sort -R | head -1
) | tee -a speedtest-log.json
sleep 600

This checks a random nearby server every 10 minutes.

· 2 min read

In certain scenarios, I've found it useful to use our production app's Read Replica as a source for manual testing. It's not something I'm reaching for often but there are definitely cases where our seed data just doesn't cut it.

Since it's a read replica, no writes can be made to it and I don't have to worry (too much) about harming production. You'll want to make sure any external user operations aren't configured to happen automatically (e.g. sending email, cropping avatars, etc).


In order to assign a different DATABASE_URL to a review app, you'll need to destroy the postgres attachment on your review app. I knock this out by chaining some commands together:

· 3 min read

After running brakeman you'll get a report and, if there are new warnings, it will exit with a status code of "3". Typically, I only see two types of output from Brakeman. Either a large report where there are new warnings or a short report which is saying Brakeman is out of date.

I'll briefly explain resolving both.

Resolving New Warning(s) Detected

The long report.

Run brakeman -I to get an interactive console for ignoring warnings. It will analyze your code base and then prompt you for where to find the ignore file. I've always used the default location of config/brakeman.ignore, so I simply press Enter to accept the default.

· 4 min read

If you would like to have great, clean sounding audio in your meetings, podcasts, or videos. Purchase the microphone and audio interface that I recommend and use below.


I use the Audio-Technica AT875R shotgun microphone.

I place it 3-5 inches from my mouth using a boom arm attached to my desk. Since I type on that desk, I use a shock mount.

Since this is a shotgun mic, it works great from a distance. I can position the mic about 6-8 inches from my mouth to get it out of a video head shot which I use for meetings (I have enough room for a lower third with this shot; about a 35mm focal length). But, for best sound, place it only a fist-full away.

Audio Interface

Since most microphones in this category do not have USB, you will need an interface to connect it to your computer.

· 2 min read

In a Rails app at work, we are using a PostGIS data type of geometry and we were getting this warning in our logs:

unknown OID 16391: failed to recognize type of 'geo'. It will be treated as String.

This is because by default, Active Record doesn't support the OID 16391 for this data type. We can add our own in Rails 4.1 as recommended by Rob Di Marco.