4018 cards
Linked content

CSS Support Guide for Email Clients

CSS support in major e-mail clients is horrible.

This will give you an overview what you will not be able to use across all clients.

See also

Postgresql: Paginate and count in one query using window functions

When paginating records, we usually need to know the number of total records in order to render pagination links. Popular pagination libraries like will_paginate Archive or Kaminari Archive do this for us by simply issuing an extra query, like this:

SELECT post.* FROM posts LIMIT 20 OFFSET 100;

SELECT COUNT(*) FROM posts;   

This is fine most of the time. But rarely, you might have very complicated WHERE conditions or a subquery that takes time to run. In thes...

JavaScript: Testing whether the browser is online or offline

You can use the code below to check whether the browser can make connections to the current site:

await isOnline() // resolves to true or false

Limitations of navigator.onLine

While you can use the built-in function navigator.onLine Archive (sic), it is only a hint for whether the device can access the Internet.

When navigator.onLine === false you know for certain that the user device has no connection to the Internet. This mea...


How to solve Selenium focus issues

Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.

This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.

Preventing accidental interaction with the Selenium window


Regex: Be careful when trying to match the start and/or end of a text

Ruby has two different ways to match the start and the end of a text:

  • ^ (Start of line) and $ (End of line)
  • \A (Start of string) and \z (End of string)

Most often you want to use \A and \z.

Here is a short example in which we want to validate the content type of a file attachment. Normally we would not expect content_type_1 to be a valid content type with the used regular expression image\/(jpeg|png). But as ^ and $ will match lines, it matches both content_type_1 and content_type_2. Using \A and \z will wo...

Linked content

Squashing several Git commits into a single commit

This note shows how to merge an ugly feature branch with multiple dirty WIP commits back into the master as one pretty commit.

Squashing commits with git rebase

What we are describing here will destroy commit history and can go wrong. For this reason, do the squashing on a separate branch:

git checkout -b squashed_feature

This way, if you screw up, you can go back to your original branch, make another branch for squashing and try again.


If you didn't make a backup branch and something ...

Linked contentAuto-destruct in 17 days

Updated: Unobtrusive JavaScript helper to progressively enhance HTML

I improved the compiler() function:

  • Allows multiple compilers with the same selector
  • Allows multiple destructors on the same element

You are not using filter_map often enough

Somewhat regularly, you will need to filter a list down to some items and then map them to another value.

You can of course chain map and compact, or select/filter and map, but Ruby 2.7 introduced a method for this exact purpose: filter_map Archive .

So instead of

>> [1, 2, 3, 4, 5, 6].map { |i| i * 2 if i.even? }.compact
=> [4, 8, 12]


>> [1, 2, 3, 4, 5, 6].select(&:even?).map { |i| i * 2 }
=> [4, 8, 12]

you can just do

>> [1,...
Linked content

Josh McArthur: Fancy Postgres indexes with ActiveRecord

I recently wanted to add a model for address information but also wanted to add a unique index to those fields that is case-insensitive.
The model looked like this:

create_table :shop_locations do |t|
  t.string :street
  t.string :house_number
  t.string :zip_code
  t.string :city
  t.belongs_to :shop

But how to solve the uniqueness problem?

Another day, another undocumented Rails feature!

This time, it’s that ActiveRecord::Base.connection.add_index supports an undocumented option to pass a string argument as the v...


ruby-sass: Do not use comments between selector definitions

Sass lets you easily specify multiple selectors at once like this:

    outline: 1px solid red

This will add a red outline on either real hover or when the has-hover class is present. However, adding a comment will void the definition of that line:

  &.has-hover, // From hoverable.js <-- DON'T
    outline: 1px solid red

... will simply drop the &.has-hover part in ruby-sass Archive (deprecated). [sassc](https://rubygems.org/g...


An auto-mapper for ARIA labels and BEM classes in Cucumber selectors

Spreewald Archive comes with a selector_for helper that matches an English term like the user's profile into a CSS selector. This is useful for steps that refer to a particular section of the page, like the following:

Then I should see "Bruce" within the user's profile

If you're too lazy to manually translate English to a CSS selector by adding a line to features/env/selectors.rb, we already have an [auto-mapper to translate English into ...


How to tackle complex refactorings in big projects

Sometimes huge refactorings or refactoring of core concepts of your application are necessary for being able to meet new requirements or to keep your application maintainable on the long run. Here are some thoughts about how to approach such challenges.

Break it down

Try to break your refactoring down in different parts. Try to make tests green for each part of your refactoring as soon as possible and only move to the next big part if your tests are fixed. It's not a good idea to work for weeks or months and wait for all puzzle pieces ...

Linked contentAuto-destruct in 10 days


Rack::SteadyETag Archive is a Rack middleware that generates the same default ETag Archive for responses that only differ in CSRF tokens or CSP nonces.

Changes in 0.3.0

  • Support for old Rack 1.4.7 (last version supported by Rails 3.2)
  • No longer depends on activesupport.
  • Don't depend on byebug being in the user bundle.
  • Don't raise an error when processing binary content.
  • Only strip patterns for HTML and XHTML responses.
  • Drop...
Linked contentAuto-destruct in 10 days

Updated: Be very careful with 301 and 308 redirects

  • Note that Rails sends a Cache-Control header that causes permanent redirects to not be cached.
  • Migrated examples to Mermaid graphs
Linked content

Rails: How to find records with empty associations

Imagine these models and associations:

class Deck < ApplicationRecord
  has_many :cards

class Card < ApplicationRecord
  belongs_to :deck, optional: true

Now you want to find all Decks without any Card or all Cards without a Deck.

Rails 6.1+

Rails 6.1 introduced a handy method ActiveRecord#missing Archive to find records without given associations.

SELECT "decks".*
FROM "dec...

Do not forget mailer previews

When changing code in mailers, updating the corresponding mailer preview is easily forgotten.

Mailer previews can be tested like other code as well and I sometimes add the following test to test suites:

# Make sure to require the previews
Dir[Rails.root.join('test/mailers/previews/*.rb')].sort.each { |file| require(file) }

ActionMailer::Preview.all.index_with(&:emails).each do |preview, mails|
  mails.each do |mail|
    it "#{preview}##{mail} works" do
      expect { preview.call(mail) }.not_to raise_error
Linked contentAuto-destruct in 6 days

Unpoly 2.6.0 released

This is a final maintenance release before Unpoly's next major feature drop in a few weeks.

This is also the last release with support for Internet Explorer 11. Future releases will support Chrome, Firefox, Edge and the last two majors of Safari.


The polling Archive implementation was rewritten to fix many issues and edge cases:

This website uses short-lived cookies to improve usability.
Accept or learn more