Git: Amending older commits

Lets say you need to make a change to a commit OLD_COMMIT, but this is not the most recent. If you have neither pushed nor merged it, you can do this:

  • Make a new commit now, with a message like "fix".
  • Do a
git rebase -i OLD_COMMIT~
  • In the editor window that opened, move the "fix" commit directly after the one you want to amend (so it should be the second from the top), and mark it as "fixup". Save the file.
  • If there are conflicts, solve them, add them, and do
git rebase --continue

Never use YAML.load with user input

You can get YAML.load to instantiate any Ruby object by embedding the desired class name into the YAML code. E.g. the following will create a new User object and set @email and @password to the given values:

--- !ruby/object:User
email: me@somewhere.com
password: secret

Considering the security implications, you should never trust YAML from untrusted sources. If you are looking for a simple, secure and readable data transfer format, use Object#to_json and JSON.parse.

Another way around YAML.load is [`YAML.safe_...

How to fix failing controller specs 91% of the time

If your controller spec never reaches your controller code:

  1. Make sure you are signed in.

  2. Make sure you are actually triggering a request by saying get :edit or something siliar.

  3. Know that views are not rendered by default for controller specs unless you tell them to (render_views).
    ^
    describe UsersController do
    describe '#edit' do
    it 'should work' do
    sign_in
    get :edit
    end
    end
    end

    define something like this in your spec_helper.rb:

    def sign_in(user = User....

Open a page in the default browser

Use the Launchy gem:

Launchy.open('http://www.ruby-lang.org/')

The LaTeX Font Catalogue

Gallery of fonts you can use without much hassle in LaTeX. The license of the fonts vary, but are all free. Note that the fonts not necessarily are free to distribute, and some fonts are available for non-commercial use only.

Change the current directory without side effects in Ruby

To temporarily change the current working directory in Ruby, call Dir.chdir with a block. The previous working directory will be restored when the block ends:

Dir.chdir('/usr/local') do
  # do stuff in /usr/local
end

Ruby 2.0 Refinements in Practice

The first thing you need to understand is that the purpose of refinements in Ruby 2.0 is to make monkey-patching safer. Specifically, the goal is to make it possible to extend core classes, but to limit the effect of those extensions to a particular area of code. Since the purpose of this feature is make monkey-patching safer, let’s take a look at a dangerous case of monkey-patching and see how this new feature would improve the situation.

MySQL: Select a default value for NULL fields

If you need to do calculations inside the database and can not use Ruby objects you may run into problems when encountering fields with NULL values:

SELECT foo, bar, foo - bar AS baz FROM plop;
+-----+------+------+
| foo | bar  | baz  |
+-----+------+------+
|  30 |   20 |   10 |
|  30 | NULL | NULL |
+-----+------+------+

Solve this by using IFNULL: it returns the selected value if present and a given alternative if it would select NULL:

SELECT foo, bar, foo - IFNULL(bar, 0) AS baz FROM plop;
+-...

Prototype 1.7 is out

jQuery's selector engine, live()-like event handlers, pixel-perfect layout measuring.

Virtual attributes for array fields

When a has_many association basically serves to store a list of associated strings (tags, categories, ...), it can be convenient to represent this association as a string array in the containing model. Here is an example for this pattern from the acts-as-taggable-on gem:

post = Post.last
p post.tag_list # ['foo', 'bar', 'baz']
post.tag_list = ['bam']
p post.tag_list # ['bam']

This string array tag_list is magical in several ways:

  • It is read from and written to a `has...

Install RubyMine under Ubuntu

This card explains how to install RubyMine for the first time. If you want to upgrade an existing RubyMine installation (after legacy install) to a newer version, see How to upgrade RubyMine.


Option A (new way)

Ubuntu 16.04 comes with snap, a way to package software with all its dependencies. RubyMine is also packaged as a snap.

A snap will always track a channel (like stable, beta) and automatically update to the newest version available in this channel. By default the snap daemon will check for ...

Installing Nokogiri

Because Nokogiri needs to be compiled and dynamically linked against both libxml2 and libxslt, it has gained a reputation for being complicated to install. Let’s wrassle this little myth to the ground, shall we?

Counters for Partials

When rendering a partial with the :collection option, you are automatically provided with a counter variable inside the partial template.

Hunt down that elusive debug message in Ruby

When you just went through a long debug-fest and infested your code with dozens of debug messages, it can be hard to find all those calls to puts and p. This note describes a hack that lets you trace those messages in your code.

Let's say you want to get rid of a console message "foobar". Copy the Undebug class below to config/initializers.rb. In the same initializer, type a line:

Undebug.trace_message('foobar')

Now run tests or whatever you need to do to to trigger that message. The console output should look like this:

...

Disable automatic e-mail checking in Thunderbird 3

Have you guys ever done the math on that? You asked or allowed for 24000 interruptions from literally every human being in the world who could fall onto a keyboard and make an e-mail go to you. (Merlin Mann)

So you decided to put a price on your attention and not check your e-mail 24000 times a year. A first step is to disable automatic e-mail checks in Thunderbird.

  1. Open Edit -> Account settings and select your incoming mail account.
    ...

Take care when joining and selecting on scopes

Occasionally some complex query must be processed on the database because building thousands of Ruby objects is impracticable.

Many times you would use scope options, like this:

users = User.scoped(
  :joins => 'INNER JOIN orders joined_orders ON users.id = joined_orders.user_id',
  :conditions => [ 'joined_orders.date BETWEEN ? AND ?', start_date, end_date ],
  :select => '*, SUM(joined_orders.amount) AS amount_sum',
  :group => 'users.id'
)

You get ActiveRecord objects and you can ask each of them about its `amou...

Manipulate an array attribute using multiple check boxes

E.g. when you're using a tagging gem, you have seen virtual attributes that get and set a string array:

post = Post.last
puts post.tag_list # ['foo', 'bar', 'baz']
post.tag_list = ['bam']
puts post.tag_list # ['bam']

If you would like to create a form displaying one check box per tag, you can do this:

- form_for @post do |form|
  = form.check_box :tag_list, { :multiple => true }, 'foo', nil
  = form.check_box :tag_list, { :multiple => true }, 'bar', nil
  =...

Use the back button in Cucumber

In order to go back one page in your Cucumber tests, you can use the following step definition for Capybara:

When(/^I go back$/) do
  visit page.driver.request.env['HTTP_REFERER']
end

If you're on Webrat, this should work:

When(/^I go back$/) do
  visit request.env["HTTP_REFERER"])
end

An improved version of this step is now part of our gem spreewald on Github.

Thoughtbot's experiences with headless Javascript testing

Selenium has been the siren song that continually calls out to us. Unfortunately, in practice we’ve been unable to get Selenium to run reliably for real applications, on both developers machines and on the continuous integration server. This failure with Selenium has caused us to search for alternative solutions

Change commit messages of past Git commits

To change a commit message of the most recent (unpushed) commit, you can simply use
git commit --amend -m 'new message'

To change messages of (unpushed) commits further in the past:

git rebase -i [COMMIT BEFORE THE FIRST YOU WANT TO EDIT]

Mark all messages to be changed with "edit".

Git will start the rebasing and stop at every marked commit. For each of those, do a
git commit --amend -m 'new message'
git rebase --continue

Test a gem in multiple versions of Rails

Plugins (and gems) are typically tested using a complete sample rails application that lives in the spec folder of the plugin. If your gem is supposed to work with multiple versions of Rails, you might want to use to separate apps - one for each rails version.

For best practice examples that give you full coverage with minimal repitition of code, check out our gems has_defaults and assignable_values. In particular, take a look at:

  • Multiple `sp...

Test that a select option is selected with Cucumber

This step tests whether a given select option comes preselected in the HTML. There is another step to test that an option is available at all.

Capybara

Then /^"([^"]*)" should be selected for "([^"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
  with_scope(selector) do
    field_labeled(field).find(:xpath, ".//option[@selected = 'selected'][text() = '#{value}']").should be_present
  end
end

Webrat
...

Useful collection of Sass mixins

This collection of Sass mixins enables cross-browser styling (including IE with CSS3PIE) with less lines of code.

This enables PIE for IE up to version 8 only (the first part is not possible in Haml, so use ERB):

<!--[if !IE]><!-->
  <%= stylesheet_link_tag 'screen', :media => 'screen' %>
<!--<![endif]-->
<!--[if lte IE 8]>
  <%= stylesheet_link_tag 'screen_with_pie', :media => 'screen' %>
<![endif]-->

These would be your two screen Sasses:

# screen_with_pie.sass

...

Enable SSL for Pivotal Tracker

You should never transmit sensitive data without encryption. Being logged in somewhere constitutes transmitting sensitive data.

For Pivotal Tracker:

  • Make sure you set "Always Use HTTPS" under "My Profile".
  • As you can not rely on every member of a project to have this enabled, you should also tick "Use HTTPS" on the settings page of each project.