3807 cards

How to write complex migrations in Rails

Rails gives you migrations to change your database schema with simple commands like add_column or update.
Unfortunately these commands are simply not expressive enough to handle complex cases.

This card outlines three different techniques you can use to describe nontrivial migrations in Rails / ActiveRecord.

Note that the techniques below should serve you well for tables with many thousand rows. Once your database tables grows to millions of rows, migration performance becomes an iss...

Linked content

Using ffmpeg as a HLS streaming server

A practical and detailed walk-through tutorial on using ffmpeg for live-streaming HLS, filled with real-world examples.

  • Using FFmpeg as a HLS streaming server (Part 1) – HLS Basics
  • Using FFmpeg as a HLS streaming server (Part 2) – Enhanced HLS Segmentation
  • Using FFmpeg as a HLS streaming server (Part 3) – Multiple Bitrates
  • Using FFmpeg as a HLS streaming server (Part 4) – Multiple Video Resolutions
  • Using FFmpeg as a HLS streaming server (Part 5) – Folder Structure
  • Using FFmpeg as a HLS streaming server (Part 6) – Independent Seg...
Linked content

Tailwind versus BEM

The linked article compares two approaches for writing CSS:

  • A component library (like BEM)
  • Utility classes (like Tailwind)

It's good to know the pros and cons of each approach. Although we default to BEM, you might encounter a utility approach in a client project.

Linked content

Terminator: do not broadcast to other windows

Terminator has a cool feature that allows you to split your terminal into many panels and type in all of them at the same time. It's called broadcasting and can be enabled by pressing Alt+a (and disabled by Alt+o).

However, in some circumstances it will also be broadcasted to other running instances of Terminator. This probably is not what you want and could be very dangerous (e.g. if you're logged in to a production server in a terminal that is on another workspace).

To prevent the broadcast from affecting other windows, go to `Prefer...


CSS: Combining different length units with calc()

calc() lets you mix CSS units. Ever wanted to give an element "the container's width minus 20px on each side"? Here you go:

width: calc(100% - (20px * 2));

When using Sass, you need to interpolate Sass expressions:

width: calc(100% - #{$margin})

Supported by all modern browsers and IE9+.

IIFEs in Coffeescript

In JavaScript we often use Immediately Invoked Function Expessions (or IIFEs) to prevent local variables from bleeding into an outside scope:

(function() {
  var foo = "value"; // foo is scoped to this IIFE

In Coffeescript an IIFE looks like this:

  foo = "value" # foo is scoped to this IIFE

There is also a shorthand syntax with do:

do ->
  foo = "value" # foo is scoped to this IIFE

You can also use do with arguments t...

Linked contentRepeats

How to let passenger restart after deployment with capistrano

Phusion Passenger changed the way how it gets restarted several times. Through the project's history, these all were valid:

  • touch tmp/restart.txt
  • sudo passenger-config restart-app /path/to/app
  • passenger-config restart-app /path/to/app

You should not need to know which one to use. Instead, the capistrano-passenger gem will choose the appropriate restart mechanism automatically based on your installed the passenger version.


  1. Add to your Gemfile:

    gem 'capistr...

Ruby: Comparing a string or regex with another string

In Rubocop you might notice the cop Style/CaseEquality for e.g. this example:

def foo(expected, actual)
  expected === actual

In case expected is a Regex, it suggests to change it to the following pattern:

def foo(expected, actual)

In case expected is a Regex or a String, you need to keep ===. Otherwise the actual expression is always converted to a regular expression.

# For expected === actual
foo('Test(s)', 'Test(s)') #=> true

# For expected.match?(actual)
Linked contentAuto-destruct in 27 days

Updated: Fixing flaky integration tests

Added a new section on Capybara.default_set_options. The default native fill_in clearing strategy may cause a race-condition (or similar).

Tool 8: Adjust your Capybara configuration

Capybara offers some global variables that can be fine-tuned. If your flickering tests are failing when the fill_in method is used, change the way Capybara clears a field before filling in a new value (Selenium only):

Linked contentRepeats

Passive event listeners may speed up your scroll and touch events

Scroll and touch event listeners tend to be computationally expensive as they are triggered very often. Every time the event is fired, the browser needs to wait for the event to be processed before continuing - the event could prevent the default behavior. Luckily there is a concept called passive event listeners which is supported by all modern browsers.

Below are the key parts quoted from WICG's explainer on passive event listeners. See [this demo video](https://www.youtube.com/watch?v=NPM6172...

Ruby: A short summary of available hooks in Cucumber

Here is a short summary of Cucumber hooks in Ruby taken from https://github.com/cucumber/cucumber-ruby. Note that the BeforeStep is currently not existing in the Ruby implementation of Cucumber.

Before hooks run before the first step of each scenario.

Before do |scenario|

After hooks run after the last step of each scenario, even when the step result is failed, undefined, pending or skipped.



When you want to format only line breaks, you probably do not want simple_format

For outputting a given String in HTML, you mostly want to replace line breaks with <br> or <p> tags.
You can use simple_format, but it has side effects like keeping some HTML.

If you only care about line breaks, you might be better off using a small, specialized helper method:

def format_linebreaks(text)
  safe_text = h(text)
  paragraphs = split_paragraphs(safe_text).map(&:html_safe)

  html = ''.html_safe
  paragraphs.each do |paragraph|
    html << content_tag(:p, paragraph)



Reading an element's attributes with Capybara

capybara_element['attribute_name'] allows accessing an element's attributes in Capybara.

A few examples:

# => "first-class second-class"

# => "My placeholder value"

# => "http://example.com"

# => nil

Project management best practices: Project team responsibilities

In a project team for a bigger project people have several roles:

  • Developer: at makandra
  • Project lead: at makandra
  • Project manager (PM): at makandra, external, or with the customer. In a smaller project this person is also the project lead.
  • Product owner (PO): with the customer


  • Development
  • Take responsibility for their stories. This includes always gathering all necessary information from the project lead or the PM, communicate blockers, make sure stories are merged, deployed etc.
  • Tell the project lead, if you'r...

How to negate scope conditions in Rails

Rails does not offer a "vanilla" way of negating an ActiveRecord scope. Here are two ways to do it yourself without too much effort.


class User
  scope :admins, -> { where(role: ['admin', 'superuser'] }
  # ...

Now what if we want a scope of users that are not admins? While you could declare a second scope like scope :non_admins, -> { where(role: ['guest', 'editor']) }, there are ways to use the opposite of the admins scope.

Option A: Subquery

You could just use a subquery. Doing that with scopes is easy...

Manage Linux services on the command line (Ubuntu)

Ubuntu 18.04 uses systemd to manage services.

There are basically two commands for listing all services and manipulating the state of a certain service: service and systemctl:

  • service manages System V init scripts
  • systemctl controls the state of the systemd system and service manager. It is backwards compatible to System V and includes the System V services

Therefore I prefer to use systemctl.

See which services are there

>systemctl list-units -a --type=service
  UNIT                                 LOAD      ACTI...
Linked contentRepeats

HTML file inputs support picking directories

HTML's <input type="file"> accepts a single file. You can allow multiple files via <input type="file" multiple>.
But sometimes, selecting multiple files is not enough and can be cumbersome for the user. Enter webkitdirectory:

<input type="file" webkitdirectory multiple>

Using webkitdirectory switches the browser's file picker to select a directory. All files inside that directory, and inside any nested subdirectories, will be selected for the file input.

This can be useful when users want to upload all files from a nested dire...


Pretty commit messages via geordi

Geordi provides a pretty neat way to generate beautiful commit messages according to your stories in Pivotal Tracker:

geordi commit

Geordi reads from a .geordi.yml file inside your repo and connects to Pivotal Tracker to list started and finished stories with their title. Choosing one of them generates a commit message including id and title from pivotal tracker. For example:

[#1234567] CRUD Users

Trouble shooting

If you encounter a bug like `40...

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