Falsehoods Programmers Believe About Names

I’m going to list assumptions your systems probably make about names. All of these assumptions are wrong. Try to make less of them next time you write a system which touches names.

Getting your e-mails back after upgrading Thunderbird to version 3

If you previously used version 2.x of Thunderbird and upgraded to 3.x (for example through an Ubuntu release upgrade) you might notice that Thunderbird will not show any of your old e-mails or settings.

This results from a different directory being used for storing profiles and configuration.

You can replace the blank profile with your old one like this:
cd ~
mv .thunderbird .thunderbird-invalid
cp -R .mozilla-thunderbird .thunderbird

Upon its next start, Thunderbird brings up the migration wizard introducing you to a few vers...

Working around the ancestry gem's way of object destruction

The ancestry gem allows you to easily use tree structures in your Rails application.

There is one somewhat unobvious pitfall to it: its way of applying the orphan_strategy which defines how it handles children of an object going to be destroyed.

What's this all about?

In many cases you might want to disallow destruction if there are any child nodes present. The restrict strategy does the trick but raises an exception when destroy is called:
has_ancestry :orphan_st...

Inspecting model callback chains

If you need to look at the list of methods that are called upon certain events (like before/after saving etc), do this:

Model._save_callbacks.select {|cb| cb.kind == :before}.map{ |c| c.instance_variable_get :@filter }

Rails 2

User.after_save_callback_chain

To look at the method names only, you could do something like that:

User.after_save_callback_chain.collect(&:method)

Find the newest file from shell

This can be helpful when you need the latest file inside a directory for processing in a shell script:

ls -1tr * | tail -1

Used switches

The -1 switch makes ls return 1 file per line, -t orders by modification time and -r causes sorting from oldest to newest. tail -1 then returns the last line, containing the newest file's name.

If you require only a subset of files, adjust the "*" mask accordingly or use other switches of ls.

Force RubyMine to notice file system changes

If you did file operations inside a shell or for example using Nautilus, it can take quite a while until RubyMine takes note of them and updates things like your project tree or its internal file list.

Flushing file system buffers helps you out (run it from a terminal):
sync

This is also possibly via the RubyMine menus: File → Synchronize.

Setting nil values in Machinist blueprints

Take care when trying to set attributes to nil in a blueprint.

Given the following master blueprint:
Story.blueprint do
title
author { User.make }
editor { User.make }
end

This approach will not overwrite/remove the editor defined in the master blueprint:
Story.blueprint(:draft) do
editor nil
end

...whereas this one will (note the lambda):
Story.blueprint(:draft) do
editor { nil }
end

Dealing with ActiveRecord::RecordNotSaved

If you get an ActiveRecord::RecordNotSaved error, a method inside one of your model's callback chains (before_save etc) possibly returned false.

This commonly happens when you have a method setting attributes and the last one is a boolean set to false (as the value of the last statement is returned). Fix this by simply calling true at the end of such methods:

def hide
  self.visible = false
  true
end

Note that nil won't cause this behavior. Thus, you can use an if without problems -- if you are not returning fal...

Here’s what we’ve learned about doing UI for mobile web apps with WebKit

Lately, we’ve been exploring ways to offer web apps that perform like native apps on mobile devices. For this short sprint we targeted mobile WebKit browsers—especially the default browsers on iOS and Android—because of their widespread use and excellent support for HTML5 and CSS3. Here are a few things we’ve learned along the way.

Match strings in a given order with Cucumber and Capybara

Sometimes the order in which strings appear on a page matters to you.

Spreewald gives you steps like these:

Then I should see in this order:
  | Alpha Group |
  | Augsburg    |
  | Berlin      |
  | Beta Group  |

Or, if you prefer multiline strings:

Then I should see in this order:
  """
  Alpha Group
  Augsburg
  Berlin
  Beta Group
  """

The step ignores all HTML tags and only tests on plain text.

Preload tags with acts-as-taggable-on

When you do tags with acts-as-taggable-on and want to preload associated tags, you can do so with

TaggedModel.scoped(:include => :tag)

Note however that this will only prevent tagged_model.tags from hitting the database. Using tagged_model.tag_list does not use the preloaded association.

Solve ActiveRecord::MissingAttributeError "missing attribute: foo"

Did you use the :select option in a find, and forgot to include foo?

Using SSL in Rails 3

SSL in Rails 3 is non-obvious.

Machinist: Refer to another named blueprint inside a blueprint

Note: We are talking about Machinist 1 here, Machinist 2 may have solved this or might require a different approach.


Machinist allows named blueprints (e.g. User.blueprint(:admin)) that inherit from the master blueprint (User.blueprint).

If you also want to inherit from another blueprint (e.g. if "vip" should load "premium" and the master blueprint) you can do this:
User.blueprint(:vip) do
# Fields for the vip blueprint go her...

Be careful with Array(...)

A popular ruby idiom I keep stumbling upon is
def do_some_thing_for(values)
values = Array(values)
values.each { ... }
end

The intent is to allow the user to pass in arrays as well as scalar values, since
Array("foo") == ["foo"]
Array(["foo", "bar"]) == ["foo", "bar"]

But Array() actually calls to_a on its arguments, which may not always do what you expect. For example
Array("foo \n bar") == ["foo \n", "bar"]

Deliver Paperclip attachments to authorized users only

When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.

  1. Deliver attachments through Rails

The first way is to store Paperclip attachments not in the default public/system, but in a private path like storage inside the current release. You should prefer this method when dealing with sensitive data.

Make ...

Install the Nokogiri gem on Ubuntu servers

You need to install the following packages before you can build the Nokogiri gem:

sudo apt-get install libxml2-dev libxslt1-dev

Resolve Aspell errors with your Rails application

If you get an error message like that you are missing the Aspell files a specific language:

No word lists can be found for the language "de"

Solve it by installing the proper package, e.g. on Ubuntu:

sudo apt-get install aspell-de

Prevent SSH from timing out

If you have problems with SSH session timing out, add the following to your /etc/.ssh/config:

Host *
  ServerAliveInterval 55
  ServerAliveCountMax 2

Using the full power of have_css

Capybara's has_css? matcher has a couple of options you might find useful.

Check that a selector appears a given number of times

Use the :count option like this:

Then /^I should see (\d+) users?$/ do |count|
  page.should have_css('ul#users li', :count => count.to_i)
end

Check that a selector has a given text content

Use the :text option like this:

Then /^I should see a user with name "([^\"]*)"$/ do |nam...

apotonick's hooks at master - GitHub

Hooks lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as you run the hook.

Even with bundler your gem order can be significant

Even when you're using bundler, it might be significant in which order your gems are listed in your Gemfile. This can happen when gems are running around calling require or require_dependency on other gems or application classes when loaded (don't do that!).

A known culprit of this is the (otherwise wonderful) resource_controller gem, which requires ApplicationController when loaded. When your ApplicationController requires later-loaded gems when loaded, Rails will not boot.

He...

An obscure kernel feature to get more info about dying processes

This post will describe how I stumbled upon a code path in the Linux kernel which allows external programs to be launched when a core dump is about to happen. I provide a link to a short and ugly Ruby script which captures a faulting process, runs gdb to get a backtrace (and other information), captures the core dump, and then generates a notification email.

Inline if-then-else in MySQL queries

It can be useful to have a Ruby expression like condition ? positive_case : negative_case in MySQL queries:

UPDATE users SET monthly_debit = IF(subscriber, 19, 0)