Check that a text field is empty with Cucumber

This will not work (it always passes):

Then the "Title" field should contain ""

The value is turned into a regular expression, and an empty regular expression matches any string!

Do this instead for Capybara:

Then the "Title" field should contain "^$"

And do this step for Webrat:

Then /^the "([^"]*)" field should( not)? be empty$/ do |field, negate|
  expectation = negate ? :should_not : :should
  field_labeled(field).value.send(expectation, be_blank)
end

Define an array condition that selects on dynamic columns

For some reason you want to define a find condition in array form. And in that condition both column name and value are coming from user input and need to be sanitized.

Unfortunately this works in SQLite but does not in MySQL:

named_scope :filter, lambda { |attribute, value|
  { :conditions => [ 'articles.? = ?', attribute, value ] }
}

The solution is to use [sanitize_sql_array](http://apidock.com/rails/ActiveRecord/Base/sa...

Run a single example group in RSpec

To only run a single describe/context block in a long spec, you can say

spec spec/models/note_spec.rb:545

... where the describe block starts at line 545.

Note: This will only run examples that are direct children of this block, not descendants further down (when nesting describe/context blocks).

You may also pass the line of an it block to run this exact one.

How to collect a Hash from an Array

There are many different methods that allow mapping an Array to a Hash in Ruby.

Enumerable#index_by (any Rails)

users = User.all
users_by_id = users.index_by(&:id)
{
  1 => #<User id: 1, name: "Alice">,
  2 => #<User id: 2, name: "Bob"> 
}

In case of a duplicate, the last entry wins.

Enumerable#group_by (Ruby 1.8.7+)

Use group_by when duplicates are possible.
Hash values are always an Array of elements per group.

users = User.all
users_by_nam...

Find files modified since a given timestamp

If you need to find all files inside a directory that were modified in the last 24 hours you can do this:

find . -mtime 1

You can also refer to another file's timestamp like this:

find . -cnewer other_file

This can be used to check against a specific timestamp, too. This is how you check for all files modified today (since 00:00):

touch -t `date +%m%d0000` /tmp/$$
find . -cnewer /tmp/$$

Note that $$ returns the current bash's PID so you will get some file like /tmp/12345 that stays the same for the current shell. This...

Create a valid RSS feed in Rails

This will show you how to create a RSS feed that the Feed Validator considers valid.

Note that RSS is a poorly specified format. Consider using the Atom builder to make an Atom feed instead. Write a note here if you do.

  1. Controller

Create a FeedsController to host the RSS feed. Such a controller is also useful to host other data feeds that tend to gather over the lifetime of an application, e.g. sitemap.xml.:

class...

Rename hash keys

If you want to rename a key of a Ruby hash, this could help you out.
Just put it into something like config/initializers/hash_move.rb.

Install RubyGems on Ubuntu/Debian

First of all: You could just use RVM which would make the pain go away. If for some reason you can't, proceed.


Do not use rubygems from the apt repository.

  1. Get the latest RubyGems TGZ
  2. Change to the download directory and extract it:\
    tar xvfz rubygems-1.3.7.tgz
  3. If you previously had RubyGems installed via apt: \
    sudo apt-get remove rubygems
  4. Install RubyGems:\
    cd rubygems-1.3.7 && sudo ruby setup.rb
  5. Link gem to gem1.8:\
    `sudo ...

Remove resource fork files from a FAT volume on MacOS

Be careful!
The following solution will delete files on a volume. If you don't know exactly what you're doing, you can run into big trouble with your computer.

I play mp3 files on my car stereo that are stored on a SD-Card.
When I've copied those mp3 files to the FAT formatted SD-Card on my Mac, then I will see those nasty resource fork files (beginning with "._") for every file and folder on my car stereo. In most cases those resource fork files are important and invisible and don't bother you – on my car stereo ...

Understand ActiveRecord::ReadOnlyRecord error

When you load a record with find options that have SQL fragments in :select or :joins, ActiveRecord will make that record read-only. This is a protective measure by Rails because such a record might have some additional attributes that don't correspond to actual table columns.

You can override that precaution by appending :readonly => false to affected find options or scope options.

When sessions, cookies and Clearance tokens expire and how to change it

Expiration of Rails sessions

By default Rails sessions expire when the user closes her browser window.

To change this edit your config/initializers/session_store.rb like this:

ActionController::Base.session = {
  :key          => '...',
  :secret       => '...'
  :expire_after => 10.years
}

In older Railses the initializer is not available. Set the option in the environment.rb instead:

config.action_controller.session = {
  :key          => '...',
  :secret       => '...'

...

Flash SWF movie bleeds into an element covering it

Embedded Flash movies do not always obey element order and z-index.

To fix this, set the wmode attribute to transparent in both <object> and <embed> tags:

<object ... >
  <param name="wmode" value="transparent" />
  <embed ... wmode="transparent" />
</object>

Strip carriage returns in submitted textareas

When submitting textareas, browsers sometimes include carriage returns (\r) instead of just line feeds (\n) at the end of each line. I don't know when this happens, and most of the time it doesn't matter.

In cases where it does matter, use the attached trait to remove carriage returns from one or more attributes like this:

class Note
  does 'strip_carriage_returns', :prose, :code
end

Here is the test that goes with it:

describe Note do

  describe 'before_validation' do...

Split nested block parameters

If you iterate over a collection of arrays, you can destructure the arrays within the block parameters:

movies_and_directors = [
  ['The Big Lebowski', 'Coen Brothers'],
  ['Fight Club', 'David Fincher']
]
movies_and_directors.each do |movie, director|
  # do something
end

For nested array (e.g. when you use each_with_index), you can use parentheses for destructuring:

movies_and_directors.each_with_index do |(movie, director), index|
  # do something
end

Fix a spec that only runs when called directly

When a spec only runs when it is called directly, but not as part of the whole test suite, make sure the filename is foo_spec.rb instead of just foo.rb.

Enable tab dragging in RubyMine

Since RubyMine 3.1 you can drag tabs across panes/windows and out of the main window to create new windows.

For any version below 3.1 do it like this (will only allow dragging tabs inside their pane, not across panes):

  1. File → Settings
  2. Editor → Editor Tabs
  3. Check "Show tabs in single row"

Seriously.