Spreewald: Content-Disposition not set when testing a download's filename

Precondition

  • You are not using javascript tests
  • The file is served from a public folder (not via controller)

Problem description

If you deliver files from a public folder it might be that the Content-Disposition header is not set. That's why the following spreewald step might raise an error:

Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
     got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)

Solution

One solution...

Capybara steps to match stuff within any selector

These steps are now part of Spreewald.

Since Capybara 0.4.1 a within scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.

In order to perform a test or action in all matching elements, do not use within but prefer the attached "inside any" Cucumber steps like these:

When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"

How to fix broken font collisions in wkhtmltopdf

If you are using PDFKit / wkhtmltopdf, you might as well want to use custom fonts in your stylesheets. Usually this should not be a problem, but at times they include misleading Meta-information that leads to a strange error in the PDF.

The setup

  • The designer gave you two fonts named something like BrandonText-Regular and BrandonText-Bold. (With flawed Meta-information)
  • You have a HTML string to be rendered by PDFKit
  • For demonstration purposes, this strin...

How to add a custom dictionary to Ruby Mine

  1. Download the dictionary from http://www.winedt.org/dict.html, e.g. http://www.winedt.org/dict/de_neu.zip
  2. unzip de_neu.zip
  3. mkdir ~/Documents/dic
  4. iconv -f UTF-16 -t UTF-8 de_neu.dic -o ~/Documents/dic/de_neu_utf8.dic
  5. In RubyMine: Go to Settings (CTRL + ALT + S) > Editor > Spelling > Dictionaries and add the folder ~/Documents/dic

How to move all files in a folder to a new subfolder

Let's say you have a folder images and want to to move all files in there to a new subfolder public.

cd images
mkdir public
mv !(public) public

The !(public) excludes the new subfolder itself from being moved.

How to exploit websites that include user input in their CSS

The linked article shows how to exploit websites that include unsanitized user input in their CSS.

Although the article often mentions React and CSS-in-JS libraries, the methods are applicable to any web app that injects user input into style tags or properties.

Also, sanitizing user input for CSS injection is much harder than sanitizing HTML.

A Theme Switcher

Hack to implement an inverted "night mode" theme with a few lines of CSS.

Colors in images are preserved.

Bundler 2 will rename Gemfile and Gemfile.lock

TL;DR: Bundler 2.0 will rename Gemfile to gems.rb and Gemfile.lock to gems.locked (sic).

The old filenames will be supported until the release of Bundler 3.0.

Some more breaking changes here.

Association to polymorphic model does not determine inverse_of automatically

You need to set the :inverse_of option manually for relations that have an association to a polymorphic model. Otherwise you will not be able to save a record with a nested polymorphic association.

class Event < ApplicationRecord
  has_many :letters, as: :record
end

class Letter < ApplicationRecord
  belongs_to :record, polymorphic: true
end

event = Event.new.letters.build
event.save! # => ActiveRe...

How to enable the Thinkpad microphone mute key on Ubuntu 16.04

While the hardware mute button of my Lenovo x230 worked on Ubuntu 14.04 out of the box, it does not on Ubuntu 16.04. It is fairly simple to fix, though.

There is an extensive answer on Ask Ubuntu, but only part of it was required for me. Here is the gist of it.

  1. Open a terminal

  2. Run acpi_listen and press the mute key. You should see something like this:

    button/f20 F20 00000080 00000000 K
    

    Press Ctrl+C to exit.

  3. Run amixer scontrols. You will see multiple lines, one of which sh...

Rails: render a template that accepts a block by using the layout option of render

Let's say you have a form that you render a few times but you would like to customize your submit section each time. You can achieve this by rendering your form partial as layout and passing in a block. Your template or partial then serves as the surrounding layout of the block that you pass in. You can then yield back the form to the block and access the form in your block.

-# record/_form.haml

= form_for record do |form|
  -# ...
  .form-actions
    yield(form)
  

In order to make your template record/_form.haml accept a...

How to change the class in FactoryBot traits

FactoryBot allows a :class option to its factory definitions, to set the class to construct. However, this option is not supported for traits.

Most often, you can just define a nested factory instead of a trait, and use the :class option there.

factory :message do
  factory :reply, class: Message::Reply do
    # ...
  end
end

If you need/want to use traits instead (for example, it might make more sense semantically), you can not use a :class on a trait.

In that case, use initialize_with to define the record's constr...

Import Excel files without running into memory limitations

There are several gems that make it easy to read and process xlsx files. Parsing the entire file at once however is error-prone since each cell is transformed to a ruby object - sometimes including thousands of formatted but empty cells.

As of today, I found two promising alternatives that provide a stream-based access to spradsheet rows:

  • Roo supports multiple spreadsheet types like ODS or CSV and has a quite large contributor base
  • [Creek](https://github.com/pythonicrubyis...

Ubuntu MATE: Fixing ALT + TAB being really slow

On my Ubuntu MATE machine, switching applications with ALT + TAB was impossible, because it took nearly 2 seconds. The culprit appears to be an "UX improvement" gone bad: MATE renders a live screenshot of each running application inside the application switcher.

Fixing this is simple:

  • Open "Window Preferences"
  • Either uncheck "Enable software compositing window manager" or check "Disable thumbnails in Alt-Tab"

Sentry: How to get a list of events that is programmatically processable

The linked documentation explains how to get a JSON list of the latest 100 events of a given issue. Simply open this URL while logged in:

https://sentry.io/api/0/issues/<issue id>/events/

Postgres: How to force database sessions to terminate

If another session is accessing your database you are trying to reset or drop you might have seen the following error:

PG::ObjectInUse: ERROR:  database "foo_development" is being accessed by other users
DETAIL:  There is 1 other session using the database.

This could be the rails server, rubymine and many more. Beside terminating the session connection manually you can also find out the pid and kill the process.

1. rails db
2. SELECT * FROM pg_stat_activity;

datid            | 98359
datname          | foo_developm...

How to pair a Bose Quiet Comfort 35 with your Ubuntu computer

You need to disable "Bluetooth low energy", then follow these core steps:

  1. Make sure the headphones are in pairing mode.
  2. Pair with System Settings > Bluetooth. On 16.04 I had to choose "proceed without pairing" and enter the PIN "0000"
  3. Select & test the headphones in System Settings > Sound. Choose High Fidelity Playback (A2DP Sink).

I also had to install a package with sudo apt-get install pulseaudio-module-bluetooth and load it with pactl load-module module-bluetooth-discover. Put the latter command into ~/.bashrc or you'll...

JavaScript bookmarklet to click an element and copy its text contents

Here is some JavaScript code that allows you to click the screen and get the clicked element's text contents (or value, in case of inputs).

The approach is simple: we place an overlay so you don't really click the target element. When you click the overlay, we look up the element underneath it and show its text in a browser dialog. You can then copy it from there.

While moving the mouse, the detected element is highlighted.

Here is the one-liner URL that you can store as a bookmark. Place it in your bookmarks bar and click it to activate....

Custom Ruby method Enumerable#count_by (use for quick statistics)

I frequently find myself needing a combination of group_by, count and sort for quick statistics. Here's a method on Enumerable that combines the three:

module Enumerable
  def count_by(&block)
    list = group_by(&block)
      .map { |key, items| [key, items.count] }
      .sort_by(&:last)
      
    Hash[list]
  end
end

# Returns a Hash of { key => count } pairs (see below)

Just paste that snippet into a Rails console and use #count_by now!

Usage examples

  • Number of email addresses by domain:
> User.all.co...

Async/Await Will Make Your Code Simpler

Sometimes modern Javascript projects get out of hand. A major culprit in this can be the messy handling of asynchronous tasks, leading to long, complex, and deeply nested blocks of code. Javascript now provides a new syntax for handling these operations, and it can turn even the most convoluted asynchronous operations into concise and highly readable code.

JavaScript: How to query the state of a Promise

Native promises have no methods to inspect their state.

You can use the promiseState function below to check whether a promise is fulfilled, rejected or still pending:

promiseState(promise, function(state) {
  // `state` now either "pending", "fulfilled" or "rejected"
});

Note that the callback passed to promiseState will be called asynchronously in the next [microtask](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/...

Vagrant: create entry for box in .ssh/config

If you want to ssh into your vagrant box without switching into the project directory and typing vagrant ssh, you can also create an entry directly in ~/.ssh/config. This will allow you to use ssh <my-box> from anywhere. Simply paste the information provided by vagrant ssh-config to your ~/.ssh/config-File: vagrant ssh-config >> ~/.ssh/config

Example:

$ vagrant ssh-config
Host foobar-dev
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  Id...

How to install a current version of git to your Ubuntu machine

As described by the linked Stackoverflow answer, run these commands:

sudo add-apt-repository ppa:git-core/ppa -y
sudo apt-get update
sudo apt-get install git
git --version

This will get you Git 2.6.4 (as of Dec 2015).

Troubleshooting

If you don't have add-apt-repository yet, install it with:

sudo apt-get install python-software-properties software-properties-common

Understanding Scope in Ruby

Scope is all about where something is visible. It’s all about what (variables, constants, methods) is available to you at a given moment. If you understand scope well enough, you should be able to point at any line of your Ruby program and tell which variables are available in that context, and more importantly, which ones are not.

The article gives detailed explanation on the variable scope in ruby with examples that are easy to understand. Every ruby developer should at least know the first part of the article by heart. The second half ...