Asset pipeline may break Javascript for IE (but only on production)

If some of your JavaScripts fail on Internet Explorer, but only in staging or production environments, chances are that JavaScript compression is the culprit.

By default, Rails 3.2 compresses JavaScript with UglifyJS. I have seen a few cases where this actually breaks functioning JavaScript on IE (one example is the CKEditor).

I fixed this by switching to Yahoo's YUI Compressor.

To do this, do the following:

  • replace the uglifier gem with the yui-compressor gem...

Cucumber step to interact with an iframe using Capybara webdriver

Give your iframe a name attribute (i.e. <iframe name="myframe">) and then simply use

When I press "Foo" in the iframe "myframe"
Then I should see "Bar!" in the iframe "myframe"

Step as follows:

Then /^(.*) in the iframe "([^\"]+)"$/ do |step, iframe_name|
  browser = page.driver.browser
  browser.switch_to.frame(iframe_name)
  step(step)
  browser.switch_to.default_content
end

Machinist blueprints do not work with a column :display

This didn't work for me. Seems display is already taken in Machinist.

# in spec/support/blueprints.rb
Partner.blueprint do
   company_name
   display { true }
end

Unsaved record disappears when assigning to an association

If this happens to you:

user.avatar = Avatar.new
user.avatar  # => nil

(where avatar is a belongs_to), you probably declared your association incorrectly.

Always do

class User < ActiveRecord::Base
  belongs_to :avatar
end

and never

class User < ActiveRecord::Base
  belongs_to 'avatar'
end

exception_notification: Send exception mails in models

You're using exception_notification and want to send exception mails within a model. Here's how.

The ExceptionNotifier class has a method notify_exception for that. Simply pass an exception:

ExceptionNotifier.notify_exception Exception.new("testfoo")

=> #<Mail::Message:77493640, Multipart: false, Headers: <Date: Mon, 24 Sep 2012 13:37:00 +0200>,
<From: foo@example.com>,
<To: ["fail@failtrain.com", "fail@failbus.org"]>,
<Message-ID: <5060543b3759_212311986a0305e...

Git: How to look at the stash

Browsing the git stash is a bit tricky. Here is how to see the changes without applying them:

git command on the console

The following will give you the diff of the topmost stash item:

git stash show -u

But what about other items on the stash?
Well, you can list them like this:

$ git stash list
stash@{0}: WIP on feature/foo
stash@{1}: WIP on feature/bar
stash@{2}: WIP on fix/baz

All those stashed changes have their own reference (like branch names) that you can look at, like `stas...

Migrating to Spreewald

This describes how to migrate an existing cucumber test suite to Spreewald.

  1. Add the gem

  2. Include spreewald into your cucumber environment by putting
    require 'spreewald/web_steps'
    require 'spreewald/email_steps'
    # ...
    or just
    require 'spreewald/all_steps'
    into your support/env.rb.

  3. Look through your step definitions for everything that might be included in Spreewald. Candidates are web_steps, shared_steps, table_steps, `em...

How to not leave trailing whitespace (using your editor or Git)

There is no reason to leave trailing whitespace characters in your project's files, so don't add any.

A git diff --check will tell you if there are any and you should not commit when you see them. So go ahead and switch your editor/IDE to automatically remove them for you.
Below are a few instructions on how to get them removed by your favorite IDE or editor.

Note that except for RubyMine, the following changes will remove trailing white-space on all lines, not only those that you changed.
While this should not be a problem if your proje...

Using before(:context) / before(:all) in RSpec will cause you lots of trouble unless you know what you are doing

TL;DR Avoid before(:context) (formerly before(:all)), use before(:example) (formerly before(:each)) instead.

If you do use before(:context), you need to know what you are doing and take care of any cleanup yourself.

Why?

Understand this:

  • before(:context) is run when the context/describe block begins,
  • before(:context) is run outside of transactions, so data created here will bleed into other specs
  • before(:example) is run before each spec inside it,

Generally, you'll want a clean setup for each s...

Paperclip: undefined method `to_file' for #<Paperclip::Attachment:0000> (NoMethodError)

to_file has been removed in Paperclip 3.0.1.

Instead of using File to access Paperclip storage objects (like this: File.read(file.to_file.path)) you can use

Paperclip.io_adapters.for(file).read

Git basics: checkout vs. reset

Today I got a better understanding of how git works, in particular what git checkout and git reset do.

Git basics

  • A commit holds a certain state of a directory and a pointer to its antecedent commit.
  • A commit is identified by a so-called ref looking something like 7153617ff70e716e229a823cdd205ebb13fa314d.
  • HEAD is a pointer that is always pointing at the commit you are currently working on. Usually, it is pointing to a branch which is pointing to that commit.
  • Branches are nothing but pointers to commits. Y...

CSS Animations Media Queries

CSS transitions make your responsive websites smoother and more professional. It's easy and already there. Use it!

ActionMailer sometimes breaks e-mails with multiple recipients in Rails 2

The ActionMailer in Rails 2 depends on a buggy version of TMail, which sometimes inserts a blank line into the mail header when sending a mail to multiple recipients. This makes the header end prematurely.

The reason why this is not exploding in your face all the time is that when you are relaying your e-mail through an MTA like Exim, it will fix this for you.

Fix for Rails if you don't have an awesome MTA

TMail is no longer maintained. The bug is fixed...

How to convert an OpenStruct to a Hash

Simply use OpenStruct#to_h to receive an OpenStruct's hash representation.
In older Rubies you need OpenStruct#marshal_dump instead.

Ruby 2.0+

>> OpenStruct.new(foo: 23, bar: 42).to_h
=> { :foo => 23, :bar => 42 }

Ruby 1.9.3 and 1.8.7

>> OpenStruct.new(:foo => 23, :bar => 42).marshal_dump
=> { :foo => 23, :bar => 42 }

Both approaches will return the underlying hash table (a clone of it in Ruby 2.0+).

Distribute files from a private bucket on AWS S3

Given you store files on Amazon S3 and you need to stream those files out to people while you don't want them to be able to distribute the content simply by sharing the S3 URL.

You could either mark the bucket as private and fetch the appropriate files from S3 to your application server and stream them to the client finally. While this is possible, I'd recommend to use what AWS calls "Query String Authentication".

If you're using Paperclip you can chose between two sto...

Create autocompletion dropdown for Cucumber paths in Textmate

Ever wanted autocompletion for paths from paths.rb in Cucumber? This card lets you write your steps like this:

When I go to path *press tab now* # path is replaced with a list of all known Cucumber paths

This is how you do it

(key shortcuts apply for TextMate2)

  1. Open the bundle editor (ctrl + alt +  + B)

  2. Create a new Item ( + N), select "Command"

  3. Paste this:
    ^
    #!/usr/bin/env ruby -wKU
    require File.join(ENV['TM_SUPPORT_PATH'], 'lib', 'ui.rb')

    cucumber_paths = File.join ENV['TM_PROJECT_DIRECTORY'], 'features'...

BigVideo.js - The jQuery Plugin for Big Background Video

This plugin makes it easy to add fit-to-fill background video to websites. It can play silent ambient background video (or series of videos). Or use it as a player to show video playlist. BigVideo.js can also show big background images, which is nice to have for showing big background images for devices that don’t have autoplay for ambient video.

Highlight current navigation item with Staticmatic

StaticMatic is a nice tool to build simple static websites.
In case you want to have some nifty styles on the navigation item that is currently active, you can use this:

=link 'Aktuelles', :class => (current_page =~ /aktuelles/) ? 'current' : 'default'

Keep in mind that current_page gives you the full relative path of your page. raise current_path in case you're not sure.

I know there is an navigation helper out there. I did not use it and also did not want to migrate.

"command not found" bash function

If you type a command in your bash that doesn't exist you get this:

bash: foo: command not found

or if you have installed the command-not-found package on ubuntu/debian:

The program 'foo' can be found in the following packages:
* foobar
* barfoo
Try: sudo apt-get install <selected package>
-bash: foo: command not found

But you can customize this with the command_not_found_handle function which you can add to your .bashrc.

This is something I've tried:

function command_not_found_handle {
  ssh $...

See which MySQL database is currently in use

When you work in the MySQL console and you want to see which database is used, type:

SELECT database();

The result you see is the database you would activate with

USE database_name;

Test meta-refresh redirects with Cucumber

The step definition below allows you to write:

Then I should see an HTML redirect to "http://www.makandracards.com" in the page head

Capybara

Then /^I should see an HTML redirect to "([^\"]*)" in the page head$/ do |redirect_url|
  page.should have_xpath("//meta[@http-equiv=\"refresh\" and contains(@content, \"#{redirect_url}\")]")
end

To find meta tags with Capybara, you can also use page.find('meta', visible: false).

Fix error: Invalid gemspec / Illformed requirement

When you get an error like this:

Invalid gemspec in [/opt/www/foo-project.makandra.de/shared/bundle/ruby/1.8/specifications/carrierwave-0.6.2.gemspec]: Illformed requirement ["#<YAML::Syck::DefaultKey:0x7fda6f84d2e8> 1.1.4"]

... the machine's Rubygems needs to be updated.

If that happens on your local machine

  • Manually remove the offending's gem files and specifications. The paths will be something like /usr/lib/ruby/gems/1.8/gems/your-broken-gem and `/usr/lib/ruby/gems/1.8/specificatio...

Manage ssh keys with Keychain

Keychain helps you to manage ssh and GPG keys in a convenient and secure manner. It acts as a frontend to ssh-agent and ssh add, but allows you to easily have one long running ssh-agent process per system, rather than the norm of one ssh-agent per login session.

This dramatically reduces the number of times you need to enter your passphrase. With keychain, you only need to enter a passphrase once every time your local machine is rebooted. Keychain also makes it easy for remote cron jobs to securely "hook in" to a long running ssh-agent p...

Meny - A three dimensional and space efficient menu concept

Stuff like this is now possible in Webkit browsers, Firefox and IE10.