How to fix "Exit with code 1 due to network error: ProtocolUnknownError" with wkhtmltopdf

New versions of wkhtmltopdf dissallow file:// URLs by default. You can allow them by passing --enable-local-file-access.

If you are using PDFKit, set the option

PDFKit.configure do |config|
  config.default_options = {
    enable_local_file_access: true,

This will be necessary in many setups to allow wkhtmltopdf to fetch assets (such as stylesheets) from the filesystem.

Note on security

Allowing this poses some risk when you render user input, since it might be feasible to include data from the local filesyste...

Git commands to discard local changes

Use case

If you have uncommited changes (you can always check by using git status), which you want to discard.
Now you have several options to discard these depending on your exact situation.


The headlines will differentiate the cases whether the files are staged or unstaged.

Staged And Unstaged Changes

Revert all changes to modified files (tracked and untracked)

git reset --hard

If you might want to use the changes later on

git stash will add the changes to the stash, reverting the local repository to H...

RubyMine: Find and Replace with Regex (Capture Groups and Backreferences)


In RubyMine you can use find and replace with capture groups (.*?) and backreferences $1 (if you have several groups: $[Capture-Group ID]).
Named captures (?<text>.*) are also supported.


Replace double quotes with single quotes

If you want to replace double quotes with single quotes, replacing every " with a ' is prone to errors. Regular expressions can help you out here.

  1. Open find and replace
  2. Activate the regex mode (click on the .* icon next to the "find" field).
  3. Fill in f...

SEO: The subtle differences of robots.txt disallow vs meta robots no-index

The robots.txt file and <meta name="robots"> HTML tag can be used to control the behavior of search engine crawlers. Both have different effects.


Marking a URL path as "disallowed" in robots.txt Archive tells crawlers to not access that path.

robots.txt is not a guarantee for exclusion from search engine results.

A "disallowed" URL might be known from an external link, and can still be displayed for a matching search.
Example: even if /admin is disallowed in robots.txt, `/admin/som...

Do not use "flex: 1" or "flex-basis: 0" inside "flex-direction: column" when you need to support IE11

Flexbox is awesome. Most of it even works in IE11, but flex: 1 won't work reliably in Internet Explorer.
This it because implicitly sets flex-basis: 0 which IE fails to support properly.


Consider the following HTML and CSS.

<div class="container">
  <div class="child">
  <div class="bar">
.container {
  display: flex;
  flex-direction: column;

.child {
  flex: 1;

See it in action at Plunker Archive .



Rails: Overwriting default accessors

All columns of a model's database table are automagically available through accessors on the Active Record object.

When you need to specialize this behavior, you may override the default accessors (using the same name as the attribute) and simply call the original implementation with a modified value. Example:

class Poet < ApplicationRecord

  def name=(value)


Note that you can also avoid the original setter and directly read/write from/to the instance's attribute storage. However this is dis...

Project management best practices: Standup

If the project team consists of at least 2 members, do a daily standup. It should not take much longer than 15 minutes.


Tell everyone else

  • what you did yesterday
  • what you intend to do today
  • where you might need help or other input
  • if there are new developments everyone needs to know about

A "still working on X, will probably be done today" is totally fine. No need to tell a long story.

If you are out of work, find a new story with the others.

If there are new stories in the backlog, look at them and

  • make sure ev...

Prefer using Dir.mktmpdir when dealing with temporary directories in Ruby

Ruby's standard library includes a class for creating temporary directories. Similar to Tempfile Archive it creates a unique directory name.


  • You need to use a block or take care of the cleanup manually
  • You can create a prefix and suffix e.g. Dir.mktmpdir(['foo', 'bar']) => /tmp/foo20220912-14561-3g93n1bar
  • You can choose a different base directory than Dir.tmpdir e.g. `Dir.mktmpdir('foo', Rails.root.join('tmp')) => /home/user/rails_example/tmp/foo20220912-14...

How to get the git history of a file that does not exist anymore

If you want to see the git history of a project file, that doesn't exist anymore, the normal git log <path_to_file> won't work. You have to add certain flags to make it work:

git log --all --full-history -- <path_to_file>

Rails: Comparison of Dates - before? and after?


Since Rails 6+ you can use before? and after? to check if a date/time is before or after another date/time.


christmas = Date.parse('24.12.2022')
date_of_buying_a_gift = Date.parse('12.12.2022')

# => true
# Now you are well prepared for Christmas!! ;)

date_of_buying_a_gift = Date.parse('26.12.2022')

# => true
# Now you are too late for christmas! :(


If you want to check if a date/time is between to ot...

Statistics and Reports on Web Performance Optimization

Case studies and experiments demonstrating the impact of web performance optimization (WPO) on user experience and business metrics.

Careful: `fresh_when last_modified: ...` without an object does not generate an E-Tag

To allow HTTP 304 responses Archive , Rails offers the fresh_when Archive method for controllers.

The most common way is to pass an ActiveRecord instance or scope, and fresh_when will set fitting E-Tag and Last-Modified headers for you. For scopes, an extra query is sent to the database.

fresh_when @users

If you do not want that magic to happen, e.g. because your scope is expens...

Ruby and Rails: Debugging a Memory Leak

A memory leak is an unintentional, uncontrolled, and unending increase in memory usage. No matter how small, eventually, a leak will cause your process to run out of memory and crash.

If you have learned about a memory leak, looking at the number of Ruby objects by type can help you track it down:

> pp ObjectSpace.count_objects

Rails: Custom validator for "only one of these" (XOR) presence validation

For Rails models where only one of multiple attributes may be filled out at the same time, there is no built-in validation.

I've seen different solutions in the wild, each with different downsides:

  • Private method referenced via validate: works, but is barely portable and clutters the model.
  • Multiple presence validations with "if other is blank" each: looks pretty, but is incorrect as it allows both values to be filled in; also the error messages for a blank record are misleading.

Here is a third option: Write a custom validator to ...

JSON APIs: Default design for common features

When you build a JSON API you need to come up with a style to represent attributes, pagination, errors or including associated objects. Instead of reinventing the wheel, you may reuse successful API designs.


JSON:API Archive specifies common features found in most JSON APIs, like pagination, ordering and nested resources. The spec looks very similar to how one would build an API with Rails and uses similar patterns. Even if you don't plan on supporting the whole spec, it can still make sense to know how th...

Converting SVG to other vector formats without Inkscape

If you need to convert an SVG source to PS or EPS, the most common suggestion on the interwebs is to use Inkscape from the commandline.
Inkscape is a fairly resource-heavy tool with lots of dependencies Archive . A great alternative for converting is CairoSVG Archive .

CairoSVG is available on most Linux distros through their package management systems, e.g. apt install cairosvg on Ubuntu.
It has few dependencies (most importantly Python 3 and some related packages, but really not much)...

How to use a local gem in your Gemfile

You can use local copies of gems in your Gemfile like this:

gem 'spreewald', :path => '~/gems/spreewald'

As soon as you have bundled your project with the local copy of the gem, all code changes in the copy will be available on your project. So you can for example set a debugger or add console output in the gem and use it from your project.
If you checked out the gem with your versioning tool, you can easily reset your changes afterwards or make a pull request for the gem if you improved it.

Don't commit a Gemfile with local pat...

Helper methods - RSpec Core

You can define methods in any example group using Ruby's def keyword or define_method method. These helper methods are exposed to examples in the group in which they are defined and groups nested within that group, but not parent or sibling groups.