Adding comments to ambiguous database columns
The DB schema is the most important source of truth for your application and should be very self-explanatory. If determining the true meaning of a DB column requires historical research in your issue tracker or reverse engineering of your source code you might consider adding a comment.
Both PostgreSQL and MySQL support comments in the DB schema:
- For new columns: https://guides.rubyonrails.org/active_record_migrations.html#comments
- Changing the comment for existin...
Selenium: Fix Chrome's "Unsafe Password" Warning
tl;dr
Set
profile.password_manager_leak_detection
tofalse
in your Selenium Chrome options to disable password leak detection and suppress the warning.
Problem
When running Selenium tests with recent versions of Chrome and Chromedriver (e.g., version 136+), entering “unsafe” (weak or reused) passwords in forms triggers a browser warning:
"This password has appeared in a data breach…"
This alert can break automated test runs, especially in CI/CD pipelines.
Solution
You can **disable Chrome’s password leak ...
Using FactoryBot in Development
If you need dummy data to play around with in development, it's often faster to reuse your existing factories instead of using the UI or creating records in the Rails console. This approach saves time and gives you useful defaults and associations right out of the box.
You can use FactoryBot directly in the Rails console like this:
require 'factory_bot_rails' # Not needed if the factory_bot_rails gem is in the :development group
FactoryBot.create(:user)
You can also apply traits or override attributes:
FactoryBot.create...
How to apply transparency to any color with pure CSS
To apply transparency to an element, you can use opacity
in CSS. However, sometimes you don't want to make the entire element transparent, only a color.
Using not-so-modern CSS, you can simply generate non-opaque versions of a color. This card describes how to do that.
Note that we're not talking about defining colors with transparency. This is about the case where you have a color but need a more transparent variant of it (e.g. for a border, background, etc.), and where your component does that without defining the transparent variant ...
How to invert currentColor with pure CSS
The currentColor CSS keyword references the current text color and can be used to apply an element's text color to other properties.
Using modern CSS, you can also use it to calculate colors from it. This card describes how to invert currentColor
, but you can use this technique for other calculations as well.
How to invert currentColor
They key is CSS' hsl()
function and from
keyword for it:
--inverted-color: hsl(from ...
Selecting the nth element matching a selector
The :nth-child
pseudo class is commonly used for targeting elements based on their position within a parent container, for example the third element in a list or every even-numbered item. However, :nth-child
can do more.
In modern CSS specifications (Level 4), there’s an additional feature that lets you use :nth-child
in combination with a list of css selectors. This way, you can ta...
Git Rebase: How to squash/fixup/edit/... commits without actually rebasing (keeping the base)
Purpose:
Interactively rebase your current branch onto main
, keeping the original base commit (i.e. not rebasing onto main
directly).
Use Case:
Useful when you've branched off a long-lived feature branch and want to clean up your commits without changing the original base. Afterwards you will be able to rebase one clean commit interactively onto main without going through each commit individually using git rebase -i main
.
What it does:
- Opens an interactive rebase UI to choose squash/edit/fixup for each co...
Prevent unnecessary automated back-and-forth when sending noreply-emails
When you send automated emails from a noreply@-address, and the recipient has an out of office enabled, the autoreply bounces and they get an additional email with an error message.
To prevent the recipient's auto-response and the following error message you can set the email header Auto-Submitted: auto-generated
in your mailer, for example like this:
class NoReplyMailer < ApplicationMailer
default from: 'noreply@yourapp.com', 'Auto-Submitted' => 'auto-generated'
end
Testing Accessibility using Orca
Orca is a Linux screen reader. Since it is part of the GNOME project it should come preinstalled with Ubuntu installations.
To turn on the screen reader you can either go to Settings > Accessibility and then activate Screen Reader in the "Seeing" section or you can simply type orca
in your terminal.
Note
It may feel quite strange in the beginning to use a screen reader. It is constantly commenting on everything you do and every application you visit will be read aloud.
Once you started your screen reader you can simply navigate to w...
How to set Chrome's time zone in Selenium tests
For Selenium tests, your browser starts in your local timezone, or whatever your system's environment specifies.
This is usually good enough. To test any timezone-dependent behavior in Chrome, you can change the time zone using the Chrome DevTools Protocol.
Example
Chrome accepts any IANA time zone name, like "Europe/Berlin" or "Asia/Tokyo".
Here is the relevant command for Capybara:
page.driver.browser.execute_cdp('Emulation.setTimezoneOverride', timezoneId: 'Asia/Tokyo')
``...
Rails: Keeping structure.sql stable between developers
Why Rails has multiple schema formats
When you run migrations, Rails will write your current database schema into db/schema.rb
. This file allows to reset the database schema without running migrations, by running rails db:schema:load
.
The schema.rb
DSL can serialize most common schema properties like tables, columns or indexes. It cannot serialize more advanced database features, like views, procedures, triggers or custom ditionaries. In these cases you must switch to a SQL based schema format:
# in application.rb
config.a...
A "text-wrap: balance" fallback approach
Here is a workaround for when you want to use text-wrap: balance but must also render nicely for browsers that don't support it (mostly Safari <17.5).
Step 1: Put some <br>
s into your HTML
First, place explicit line breaks that should work for most cases.
This depends on your use case and is affected by e.g. container widths or user content.
<div class="my-element">
<p>
Average score
<br>
...
Implementing upload progress and remove button with ActiveStorage DirectUpload
DirectUpload allows you to upload files to your file storage without having to wait for the form to submit. It creates AJAX requests to persist the file within your form and wraps them in a little API. This card will show you how to use it in order to create in-place file uploads with progress and a remove button.
This is basic functionality, you may add additional elements, styles and logic to make this look fancy, but the core functionality is the same. I created a file upload that looks like this:

const svgo = require('svgo')
const options = {
// ...
loader: {
// ...
'.svg': 'copy', // this may be different...
Rails: Using PostgreSQL full-text search without a gem
PostgreSQL can cosplay as a full-text search engine. It doesn't have the features or fidelity of ElasticSearch or Algolia, but it's good enough if you just need to search and rank large volumes of text.
This card will teach you how to index, search and rank your Rails models in a PostgreSQL full-text index. We will do this without using any gems aside from ActiveRecord. While there are gems like pg_search or pg_fulltext, manual integration requires very...
RSpec: Executing specs by example id (or "nesting index")
There are several ways to run a single spec. I usually copy the spec file path with the line number of the example and pass it to the RSpec binary: bin/rspec spec/models/user_spec.rb:30
(multiple line numbers work as well: :30:36:68
). Another is to tag the example with focus: true
or to run the example by matching its name.
In this card I'd like to ...
Using Low-Level Prompts for High-Accuracy AI Coding
The key to unlocking the full potential of LLMs in coding lies in crafting precise prompts. The main challenge is learning how to structure prompts effectively to guide the model toward accurate results. Further evidence supporting this is the fact that Aider already writes ~70% of its own code (as of 02/2025). However, when starting out, your results may fall short of efficiently generating large portions of your code with the...
How to use your favorite font in Slack
In Slack, the settings dialog only offers a fixed selection of fonts. You can use any font you like using the /slackfont
command.
Fonts need to be installed on your machine. Webfonts beyond those provided by Slack won't magically work unless you install them locally.
Only the chat font can be changed. The monospaced font used for code blocks isn't easily customizable.
Example usage
-
/slackfont Comic Neue
to use "Comic Neue" (if installed) -
/slackfont system-ui
to use your desktop's system font in Slack. -
/slackfont
(withou...
Rails: Accessing strong parameters
Rails wraps your parameters into an interface called StrongParameters. In most cases, your form submits your data in a nested structure which goes hand in hand with the strong parameters interface.
Example:
curl -X POST -d "user[name]=bob" https://example.com/users
class UsersController
def create
User.create!(params.expect(user: [:name])) # Or User.create!(params.require(:user).permit(:name))
end
end
This works well most of the time...
Rails 8 introduces `params.expect`
The new params.expect
method in Rails 8 improves parameter filtering, addressing issues with malformed input and enhancing security. It provides a cleaner, more explicit way to enforce the structure and types of incoming parameters.
What changed
-
Replaces
require
andpermit
: Combines both methods for concise parameter validation. - Explicit Array Handling: Requires double array syntax to define arrays of hashes, improving clarity.
- Enhanced Validation: Ensures expected parameter structure, rejecting malformed input wi...
Specify Gemfile for bundle
Bundler allows you to specify the name of the Gemfile you want to bundle with the BUNDLE_GEMFILE
environment variable.
BUNDLE_GEMFILE=Gemfile.rails.7.2 bundle
By default, bundler will look for a file called Gemfile
in your project, but there may be cases where you want to have multiple Gemfiles in your project, which cannot all be named Gemfile
. Let's say for example, you maintain a gem and want to run automated tests against multiple rails versions. When you need to bundle one of your secondary Gemfiles, the solution above ...
Reverse lookup a fixture name by its id and table name
To reverse lookup a fixture by its table name and id, use the following approach on ActiveRecord::FixtureSet
:
table = 'users' # Specify the fixture table name
id = 123122 # Specify the ID to look for
# Find the fixture that matches the given ID
ActiveRecord::FixtureSet.all_loaded_fixtures[table].fixtures.find { |key, value| value['id'] == id }
Result Example:
[
"one", # Fixture name
#<ActiveRecord::Fixture:0x00007e79990234c8>, # ActiveRecord::Fixture object
@fixture= { ... }, # The raw fixtu...
Rails: Looking up constants by their name string
TL;DR: Rails ships two methods to convert strings to constants, constantize
and safe_constantize
. Neither is safe for untrusted user input. Before you call either method you must validate the input string against an allowlist. The only difference between the two methods is that unresolvable constants raise an error with constantize
, but return nil
with safe_constantize
. If you validate the input string against an allowlist, an error should never happen.
Preventing Dangerous Lookups
Suppose an application uses eit...