RSSAmplifier

Blog

mattbrictson.com

mattbrictson.comRSS feed ↗20 posts

Latest posts

Upgrading to PostgreSQL 17 with Homebrew

Postgres 17 has arrived! For those using Homebrew on macOS, this article offers a quick walkthrough of how to upgrade from 16 to 17, migrating over all existing data. Install PostgreSQL 17 Homebrew distributes Postgres as explicitly version-numbered packages. This allows you to have more than one version installed at a time, which is key for migrating data. First, install the new version (17).…

Building a better bin/dev script

Rails 7.2 uses the foreman gem for process management, which has serious limitations when it comes to interactive debugging. The run-pty Node package is an excellent alternative. Rails needs multiple processes Modern Rails apps often need to run multiple processes for local development. These processes include frontend watchers such as: yarn build --watch # prescribed by jsbundling-rails npx…

Build a modal form with Rails, Turbo, and the dialog element

I’ll explain the differences and benefits of Turbo Streams vs Turbo Frames in this HTML-first, test-driven tutorial. Only one line of JavaScript needed! Let’s test-drive I find that writing a simple test up front is a useful way to think through the user experience and document a to-do list for the implementation. Let’s write a quick system test to describe the behavior we want…

Simplify your Capybara selectors

How to use a Ruby-friendly syntax alternative to esoteric CSS and xpath expressions. Plus, a trick for making Capybara automatically aware of data-testid attributes. Attribute selectors in browser tests When writing browser tests in Rails with capybara, sometimes you’ll need to find an element based on an HTML attribute. A common use-case is when an element is explicitly marked with…

7 Lesser-Known Features and Changes in Rails 7.1

Rails 7.1 lacks big show-stopping additions, but there are still many improvements to the developer experience that are worth checking out. Rails 7.1 is finally here, nearly 2 years after 7.0 was released. My initial reaction was that – with a couple notable exceptions ( strict locals in ERB views and an auto-loaded lib directory , hooray!) – most of the major features in the release…

Bundler 2.4.20 understands .ruby-version files

You can now DRY up your Ruby version declarations with Bundler’s new Gemfile syntax. Version duplication A minor annoyance of developing and deploying Ruby applications is having to declare and maintain a project’s Ruby version in two separate places. 3.2.2 .ruby-version Development tools like rbenv expect a .ruby-version file. source "https://rubygems.org" ruby "3.2.2" gem "rails"…

Fixing Thor’s CLI Quirks

I’ve been wanting to build a CLI in Ruby, and Thor is the obvious library to use. But Thor has some weird behaviors that were driving me crazy. Here’s what I found, and how I extended Thor to fix it. If you’d like to skip the explanation and jump straight to the code, check out thor_ext.rb in my gem template on GitHub. You can use the template to quickly bootstrap an executable…

Speed up your default Rake task with the multitask -m option

I recently discovered that Rake has the ability to run tasks in parallel. For Rails projects with many test and linting tasks, this can be a huge time-saver. tl;dr bin/rake -m turns your default Rake task into a “multitask” that runs its prerequisites in parallel. You may need to restructure the definition of your default Rake task to take full advantage. One of my projects saw a 3x…

The Hidden Complexities of Running Shell Commands in Ruby

Did you know that system supports the equivalent of > dev/null output redirection? And that backticks raise an exception when a command isn’t found, but system does not? Let’s go on a deep dive into the Ruby standard library! What’s the big deal? It’s easy to run shell commands from Ruby, right? system "bundle install" This starts a sub-shell running the bundle install…

Safe redirects in Rails 7

Enforcing canonical URLs by redirecting to params is not safe and may raise an exception. Use strong params with allow_other_host: false for security. URLs with slugs Sometimes you’ll want to perform a redirect in a Rails controller to enforce canonical URLs. This comes into play when dealing with slugs. Take this URL, for example: https://app.example.com/projects/27-mvp-launch By Rails…

Automate Rails deployments with GitHub Actions

A continuous deployment recipe than can be applied to Tomo, Kamal, Capistrano, and other SSH-based CLI tools. I deploy all my Rails apps using Tomo 1 , a Ruby command-line tool I developed. Like Kamal, Capistrano, Mina and other similar gems, Tomo orchestrates deployments by executing scripts over SSH. Recently, I switched one of my Tomo-equipped Rails projects to GitHub Actions. My goal was to…

How to organize CSS in a Rails project

Don’t overthink it! Start with a simple base set of styles and refactor by extracting files and shared components as you go. New Rails projects start with a single CSS file: application.css . Inevitably every non-trivial app is going to have more CSS than will fit comfortably in that one file. While you may be tempted to declare a comprehensive file and folder structure up front, I suggest…

Don’t reinvent the wheel with Rails exception handling

With the built-in rescue_responses setting, you can map exceptions to error pages in a simple, declarative way. It automatically renders JSON, too! Exception handling, the hard way When dealing with third-party or custom exceptions in a Rails controller, your first instinct might be to implement a vanilla Ruby rescue . def show @invoice = ExternalInvoiceApi.find!(params[:id]) rescue…

Making the case for CSS normalize and reset stylesheets in 2023

If you’re embarking on writing CSS without a framework, adopting a normalize and reset stylesheet should be your first step. Here’s what I recommend. I often find myself writing CSS without a framework. One thing that always comes up early in a project is whether to use a CSS reset, some form of normalize, both, or nothing at all. After experimenting with all of these in recent…

Fixing slow, flaky system tests in Vite-Rails

Turn off autoBuild . By default, Vite-Rails automatically detects changes in your JavaScript, JSX, SCSS, etc. source files and then compiles them as needed. This is really convenient in local development. But when running a large test suite, this “auto build” behavior can cause problems. Sporadic failures when using Rails parallel testing Rails 6.0 introduced parallel testing , and it…

Improve your GitHub workflow with better repository defaults

Starting a new project? Set your team up for success with these opinionated GitHub repository settings. Creating a GitHub repository is one of those “set it and forget it” moments at the start of a project that maybe doesn’t get so much attention. But there are some interesting things buried in the repository settings pages that can improve your team’s PR review process,…

Tips for writing Rails tasks with Thor instead of Rake

Thor is a great way to write simple CLIs like one-off Rails scripts, but it does have its own gotchas. Here’s how to use Thor in practice. What’s wrong with Rake? Before diving into Thor, it’s worth reviewing Rake’s shortcomings as a CLI-builder. Long-story short: Accepting command-line arguments in a Rake task is awkward and conflicts with zsh ; building a simple CLI…

Applying a Rate Limit in Sidekiq

I discovered an easy way to implement job throttling using the ruby-limiter gem and the new “capsules” feature of Sidekiq 7. Overview I’ve been working on a Rails side-project where I need to frequently poll an external API for data in response to user activity. The polling takes place in the background via Sidekiq jobs. The challenge is that this external API is notoriously…

The 3 Vite plugins I use on every new Rails project

Autoprefixer, rollup-plugin-gzip, and vite-plugin-full-reload, plus some honorable mentions I’ve completely switched away from Sprockets and Webpacker and am using Vite for my current Rails projects. Here are the three plugins I like to add on top of the standard Vite-Rails setup. Autoprefixer rollup-plugin-gzip vite-plugin-full-reload 1. Autoprefixer The CSS language is a moving target, and…

Inline SVGs with Rails and Vite

Here’s one way to add Vite support to the popular inline_svg gem, plus a way to implement your own helper and skip the gem dependency altogether. The inline_svg gem is an easy and powerful tool for rendering SVGs in Rails. To my surprise, as of May 2023 it doesn’t yet support Vite out of the box. Extending inline_svg to add Vite support is pretty straightforward, though. Here’s…