Project management best practices: Budget control

When starting a project we always make a good estimate of all known requirements, and plan budgets and available developers accordingly.

Requirements change. Budgets usually don't.

To make sure a project stays on track, we update our estimates once a month and compare them to the remaining budget. If this doesn't match any more, we have to act.

To update an estimate, do the following:

  • Start with the most recent estimate for the project.
  • Which stories have been completed? Set their estimate to zero.
  • Have any requirements cha…

How to: Snom 300 firmware update

First, go to the webinterface of your phone.
Choose Software Update in the navigation on the left.

Next, you have to find the current firmware version for your model in the snom wiki. To do this, you have to follow the ? next to the Firmware text field to this page and then follow the link of the current firmware below Firmware Versions in the wiki. Now select your phone model. Next you have to choose between the minor versions. Follow the link of the most recent stable versio…

How to make select2 use a Bootstrap 4 theme

select2 is a great jQuery library to make (large) <select> fields more usable.

For Bootstrap 3 there is select2-bootstrap-theme.
It won't work for Bootstrap 4, but rchavik's fork does (at least with Bootstrap 4 Alpha 6, current version at time of writing this).

It is based on a solution by angel-vladov and adds a few fixes.

Use it by addi…


Defining and calling lambdas or procs (Ruby)

There are different ways to define a lambda or proc in ruby:

  1. with lambda-keyword (or proc for procs)

    test = lambda do |arg|
      puts arg
  2. with the lambda literal -> (since ruby 1.9.1)

    test = -> (arg) do
      puts arg

And there are different ways to call them:

  1. call (we prefer this)'hello world')
  2. Square brackets (could easily be mistaken for a hash)

    test['hello world']
  3. .() (weird, isn't it?)


Cucumber: Test that an element is not overshadowed by another element

I needed to make sure that an element is visible and not overshadowed by an element that has a higher z-index (like a modal overlay).

Here is the step I wanted:

Then the very important notice should not be overshadowed by another element

This is the step definition:

Then(/^(.*?) should not be overshadowed by another element$/) do |locator|
selector = selector_for(locator)
expect(page).to have_css(selector)
js = «-JS
var selector = #{selector.to_json};
var elementFromSelector = document.querySelector(selector)…


Efficiently add a click event handler to many elements in jQuery

When you need to add a click event handler to 50+ elements in jQuery, this might slow down the browser.

You can simply register an event at the root of the DOM instead. This waits for events to bubble up and checks whether the triggering element matches the selector:

$(document).on('click', '.dialog_link', function(event) {
    // Open dialog

Fun fact: Angular 2.0 will provide native syntax for event handlers that are registered on the document body,


Cancelling event propagation with jQuery

Within an event handler, there are no less than 4 methods to cancel event propagation, each with different semantics.

  • event.preventDefault()

    Only prevents the default browser behavior for the click, i.e. going to a different url or submitting a form.

  • event.stopPropagation()

    Only prevents the event from bubbling up the DOM. Note this effectively also cancels any event handlers attached through jQuery's live method, since those depend on bubbling.

  • event.stopImmediatePropagation()

    Prevents the event from bubbling up t…

Snom 300 with headset: Unlink ringtone volume from headset volume

If your Snom 300 always keeps the same volume for headset and ringtone (as soon as you change one you also change the other), here's what to do:

Go to your phone settings web interface, then Preferences (German Präferenzen). There is the seemingly harmless setting for Ringer Device from Headset (German Klingeltonausgabe bei Kopfhörer). Choose one: "Headset" or "Speaker". Do not select both, otherwise the ringtone volume will always be the same as the headset speaker volume!


Preload associations in loaded records

Sometimes you want to fetch associations for an ActiveRecord that you already loaded, e.g. when it has deeply nested associations.

Edge Rider gives your models a static method preload_associations. The method can be used to preload associations for loaded objects like this:

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    User.preload_associations [@user],  { :threads => { :posts => :author }, :messages => :sender }
end ...

Capistrano: Doing things on rollback

Capistrano has the concept of a "rollback" that comes in really handy in case of errors. When you notice that your recent deploy was faulty, run cap deploy:rollback and you're back with the previous release. In case of an error during a deployment, Capistrano will rollback itself.

But, you may ask, how can it know how to revert all the custom stuff I'm doing during deployment? It can't. But you can tell it how to.

Capistrano 3

Deploy and rollback are nearly identi…

Caution: Carrierwave has your file three times (temporarily)

When storing a file with Carrierwave, it is always cached prior to actually storing it. This is due to one of the great features of Carrierwave, see the link for details. Carrierwave by default 1) copies the file to the cache and then 2) copies it again to its final destination (deleting the cached file immediately after storing). This means there are 3 (three) instances of a file on the disk at some point in time, and still 2 ins…


Keeping web applications fast

Our applications not only need to be functional, they need to be fast.

But, to quote Donald Knuth,

premature optimization is the root of all evil (or at least most of it) in programming

The reasoning is that you should not waste your time optimizing code where is does not even matter. However, I believe there are some kinds of optimizations you should do right away, because

  • they are either obvious and easy
  • or they are very hard to do optimize later

This is an attempt to list some of those things:

On the server


Automated "git bisect" will make your day

So you're hunting down a regression (or just a bug) and want to use git bisect to find out when it was introduced? Smart kid.
If you have a shell command ready to reveal if your current state is good or bad, you can have git do most of the work for you.

Using git bisect run <your command> you can tell git that your command will reveal the issue; git on the other hand will use the return value of that call to decide if the state is good or bad. …

Ubuntu: Share internet connections with other computers

You can configure a Ubuntu system as a gateway in order to share it's internet connection (maybe via WLAN or tethering) with other computers on the network.

On the gateway

  • Enable ip traffic forwarding:
    • Open /etc/sysctl.conf
    • Uncomment the line

    • Reload using sudo sysctl -p /etc/sysctl.conf
  • Reconfigure ip_tables to allow NAT:
    • Download the attached file
    • Replace online_device with the name of the network device that provides the internet connection …

The many gotchas of Ruby class variables

TLDR: Ruby class variables (@@foo) are dangerous in many ways. You should avoid them at all cost. See bottom of this card for alternatives.

Class variables are shared between a class hierarchy

When you declare a class variable, it is shared between this and all descending (inheriting) classes. This is rarely what you want.

Class variables are bound at compile-time

Like unqualified constants, class variables are bound to your current scope *whe…

How to make Webpacker compile once for parallel tests, and only if necessary

Webpack is the future. We're using it in our latest Rails applications.

For tests, we want to compile assets like for production.
For parallel tests, we want to avoid 8 workers compiling the same files at the same time.
When assets did not change, we do not want to spend time compiling them.

Here is our solution for all that.

Its concept should work for all test suites. For Cucumber integration tests, place the following into features/support/webpacker.rb.

module WebpackerTestSupport
module_function def compile_once

Ruby: define a class with

This card will show you a cool way to define a class using
A common usecase for Structs are temporary data structures which just hold state and don't provide behaviour. In many cases you could use a simple hash as a data structure instead. However, a Struct provides you with a nice constructor, attribute accessors and complains if you try to access undefined attributes. Structs are easy to compare (by attributes). A struct gives meaning to the data.


Structs are great…


Execution of shell code in Ruby scripts

There are countless ways to execute shell code in Ruby. You should always use capture3, for which we have a dedicated card because it is so good.

All other methods to execute shell commands have signficant downsides, such as:

  • They do not tell you if the command has succeeded
  • They only return STDOUT, but not STDERR with error messages
  • They don't let you choose whether command output appears on the screen or not
  • They allow to inject code that will be interpreted by the shell
  • You alway…
3390 cards