Git diff a file with another revision (or branch)

git diff commit_hash -- path/to/file

Provide any commit hashes or branch names like "master" for commit_hash.

Install a specific version of a gem

To install webmock 1.5.0:

sudo gem install webmock --version "=1.5.0"

or
sudo gem install webmock -v "=1.5.0"

Prevent Bundler from downloading the internet

As a user of Bundler you have spent significant time looking at this message:

Fetching source index for http://rubygems.org/

To make Bundler skip this index update and only use installed gems, you can use the --local option:

bundle install --local

Unfortunately this does not work with bundle update.

It is said that Bundler 1.1 will use a feature of Rubygems.org that allows partial index updates. Hopefully the wh...

Generate a Unicode nonbreaking space in Ruby

Regular spaces and non-breaking spaces are hard to distinguish for a human.
Instead of using the   HTML entity or code like " " # this is an nbsp, use a well-named helper method instead.

def nbsp
  [160].pack('U*')
end

160 is the ASCII character code of a non-breaking space.

Defining and using sub-classes with modularity

Given this class:

class Foo
  class Bar
  end
end

If you want to clean up this code with the modularity gem, you might try something like this:

class Foo
  does 'bar'
end

module BarTrait
  as_trait do
    class Bar
    end
  end
end

Note that this changes Bar's full class name from Foo::Bar to BarTrait::Bar. If you have methods inside Foo (or other classes), you would have to change all references accordingly, which is quite unpleasant.

You can solve it like that:
`...

Install gems for all bundled projects

This is a bash script for those of you who need to install all gems for all projects (e.g. to get started quickly on a newly installed system).

Put it into your ~/bin/ and run it from the directory that holds your projects.

Note that, like the vanilla bundle install, this will fail whenever a new gem compiles native components and requires a missing system dependency.

Select a random table row with ActiveRecord

Use this scope:

class Stick
  named_scope :shuffled, lambda {
    last_record = last
    { :conditions => [ 'id >= ?', rand(last_record.id) ] } if last_record
  }
end

You can now pick a random stick by saying

Stick.shuffled.first

Or, if you prefer something smaller:

class Stick
  named_scope :shuffled, :order => 'RAND()'
end

Note however that you should never order by RAND() on tables that may become large some day, as this performs horribly and can kill your database server.

Test that a CSS selector is present with Cucumber

This note describes a Cucumber step definition that lets you test whether or not a CSS selector is present on the site:

Then I should see an element "#sign_in"
But I should not see an element "#sign_out"

Here is the step definition for Capybara:

Then /^I should (not )?see an element "([^"]*)"$/ do |negate, selector|
  expectation = negate ? :should_not : :should
  page.send(expectation, have_css(selector))
end

Here is the step definition for Webrat:

Then /^I should (not )?see an element "([^"]*)"$/ do |negate...

Bash Cheat Sheet (standard Emacs mode)

  • Ctrl + R Search commands you entered previously. Press Ctrl + R again to search further back, Ctrl + Shift + R searches forward again.

  • Ctrl + W Deletes from the cursor position to the left.

  • Ctrl + _ Undo. Yes, this also works with a German keyboard layout.

  • Ctrl + L Clear screen.

  • Ctrl + D _Close shell. (EOT, just like in many other shells.) Note: if you dove into another shell (e.g. with sudo su username) you will close it and return to ...

Rails 3 Remote Links and Forms: A Definitive Guide

Thanks to habits engrained by Rails 2’s link_to_remote and remote_form_for, we expect that Rails 3 would also handle the AJAX response for our remote links and forms. But it doesn’t; it leaves that for you.

Share your Internet connection under Ubuntu

This note describes how to setup a box running Ubuntu to share its Internet connection with another PC.

  • You will need two network interfaces to do this. One will connect to the Internet (e.g. UMTS card), one will share the connection with the other PC (e.g. Wired LAN).
  • On the Ubuntu PC, right-click on the connection symbol in the tray. Select Edit connections.
  • Switch to the wired LAN card. Go to Edit and set the method to Shared to other computers.
  • Connect the other PC to your wired LAN card. You can use the same cable that wo...

Terminus: a client-side Capybara driver

Terminus is a Capybara driver where most of the driver functions are implemented in client-side JavaScript. It lets you script any browser on any machine using the Capybara API, without any browser plugins or extensions.

Standalone Cucumber Test Suite

Sometimes you inherit a non Rails or non Rack based web app such as PHP, Perl, Java / JEE, etc. I like using cucumber for functional testing so I put together this project structure to use as a starting point for testing non Ruby web based applications.

Show a MySQL table's charset, collation and engine

Use this MySQL command to show further info about a table:

SHOW CREATE TABLE tags;

This will output a table schema like this:

CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_tags_on_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Request a non-HTML format in controller specs

If a controller action responds to other formats than HTML (XML, PDF, Excel, JSON, ...), you can reach that code in a controller spec like this:

describe UsersController do
  describe '#index' do
    it 'should be able to send an excel file' do
       # stubs and expectations go here
       get :index, :format => 'xls'
    end
  end
end

Remember that both the :format parameter and the HTTP_ACCEPT header can m...

Get the current layout's name in a view or partial

This returns the name (including path) of your current layout:

response.layout
=> "layouts/admin" # inside views that are using the 'admin' layout

You most likely do not need the full path, so go ahead and do this:

File.basename(response.layout)
=> "admin"

Undocumented :inverse_of option for ActiveRecord associations

You can now add an :inverse_of option to has_one, has_many and belongs_to associations.... Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.

Enable or disable Gnome desktop icons

When doing a presentation you may want to hide your desktop icons.

You can switch them off (or back on) like this:

  • Open up gconf-editor
  • Navigate to apps -> nautilus -> preferences
  • (Un)check "show_desktop"

Fix LoadError with Rails 3 applications on Passenger

After switching to Rails 3 you may get a LoadError with the following message when trying to use your application via passenger:
no such file to load -- dispatcher

Your Passenger version is most likely out of date.

Update the gem, then install the apache module again:
sudo gem install passenger
sudo passenger-install-apache2-module

Follow any instructions. Update your /etc/apache2/httpd.conf with the lines given at the end of the installation process to use the version you just installed.

Passenger ignores RailsEnv directive for Rails 3 applications

You might find that your Passenger ignores all RailsSomething directives in the vhost for your new Rails 3 application. The culprit is a file config.ru which makes Passenger consider your application a Rack (non-Rails) application.

To fix this you can either use RackEnv in lieu of RailsEnv (it works fine) or delete the config.ru. Unless you have a good reason to do so, go with RackEnv.

Migrating to RSpec 2 from RSpec 1

You will need to upgrade to RSpec >= 2 and rspec-rails >= 2 for Rails 3. Here are some hints to get started:

  • In RSpec 2 the executable is rspec, not spec.
  • RSpec and rspec-rails have been completely refactored internally. All RSpec classes have been renamed from Spec::Something to RSpec::Something. This also means that every require 'spec/something' must now be require 'rspec/something'.
  • In spec_helper.rb, Spec::Runner.configure becomes RSpec.configure
  • It has become really hard to extend specific example groups ...

Take care when merging with params

Be careful when using params.merge as params is a HashWithIndifferentAccess.

Why?

Usually this should not be an issue but it turns crazy if you try to include associated models deeper than 1 level:
options = params.merge(:include => { :user => :avatar })
Post.paginate options

When inspecting the merged params you will get something like this:
{ :include=> { "user" => :avatar }, :page => 23 }

Here the :user symbol in the hash of inclusions turned into a "user"...

Use form_for without the enclosing form tag

In rare cases you might need something like form_for (for using form builder methods on the resulting block element) but without the surrounding form. One such case would be updating some of a form's fields via XHR.

You can simply use Rails' fields_for to do things like this in your views (HAML here):

- fields_for @user do |form|
  = form.label :email, 'E-Mail'
  = form.text_field :email

You will only receive the form content you gave, no hidden inputs incl...