Delete all MySQL records while keeping the database schema

You will occasionally need to clean out your database while keeping the schema intact, e.g. when someone inserted data in a migration or when you had to kill -9 a frozen test process.

Old Capybara versions already have the Database Cleaner gem as dependency. Otherwise add database_cleaner to your *Gemfile`. This lets you say this from the Rails console:

DatabaseCleaner.strategy = :truncation
DatabaseCleaner.cl...

Synchronize a Selenium-controlled browser with Capybara

When you click a link or a press a button on a Selenium-controlled browser, the call will return control to your test before the next page is loaded. This can lead to concurrency issues when a Cucumber step involves a Selenium action and a Ruby call which both change the same resources.

Take the following step which signs in a user through the browser UI and then sets a flag on the user that was just signed in:

Given /^the user "([^"]*)" signed in (\d) days ago$/ do |name, days|
  visit new_session_path
  fill_in 'Username', :w...

Unexpected behavior when changing both an association and its foreign key attribute in ActiveRecord

When you set both a record's association and that association's foreign key attribute, Rails does not realize you are talking about the same thing. The association change will win in the next save, even if the foreign key attribute was changed after the association.

As an example, assume you have these two models:

class Group < ActiveRecord::Base
  has_many :users
end

class User < ActiveRecord::Base
  validates_presence_of :group_id
  belongs_to :group
end

We will now load a User and change both its `g...

Simple database lock for MySQL

Note: For PostgreSQL you should use advisory locks. For MySQL we still recommend the solution in this card.


If you need to synchronize multiple rails processes, you need some shared resource that can be used as a mutex. One option is to simply use your existing (MySQL) database.

The attached code provides a database-based model level mutex for MySQL. You use it by simply calling

Lock.acquire('string to synchronize on') do
  # non-th...

Escaping of quotation marks in Cucumber steps and step definitions

Issue

When you have a Cucumber step like

Then I should see "Did you see those \"quotation marks\" over there?"

you'll run into trouble. Cucumber won't take your escaped quotation marks.

Workarounds

One workaround is to write the step as regex (since there is a step taking a regex):

Then I should see /Did you see those "quotation marks" over there\?/

Keep in mind it’s a regex – escape regex characters like '?'.

When you have a Cucumber step like

Then I should fill in "query" with "\"some phrase\""

The fo...

Maximum representable value for a Ruby Time object

On 32bit systems, the maximum representable Time is 2038-01-19 03:14:07 in UTC or 2038-01-19 04:14:07 in CET. If you try to instantiate a Time with any later value, Ruby will raise an ArgumentError.

If you need to represent later time values, use the DateTime class. This is also what Rails does when it loads a record from the database that has a DATETIME value which Time cannot represent. Note that there are some [subtle differences](http://stackoverflow.com/quest...

Dump your database with dumple

This tool is used on our application servers (and called when deploying) but it also works locally.
Just call dumple development from your project directory to dump your database.


This script is part of our geordi gem on github.

RSpec < 2.11: ActiveRecord scopes must be loaded before using the "=~" matcher

To test whether two arrays have the same elements regardless of order, you can use the =~ matcher in RSpec < 2.11:

actual_array.should =~ expected_array

If either side is an ActiveRecord scope rather than an array, you should call to_a on it first, since =~ does not play nice with scopes:

actual_scope.to_a.should =~ expected_scope.to_a

If you use RSpec >= 2.11 we recommend using the match_array or contain_exactly matchers instead of =~.
Use the eq matcher only if the order of records matters.

Validate an XML document against an XSD schema with Ruby and Nokogiri

The code below shows a method #validate which uses Nokogiri to validate an XML document against an XSD schema. It returns an array of Nokogiri::XML::SyntaxError objects.

require 'rubygems'
gem 'nokogiri'
require 'nokogiri'

def validate(document_path, schema_path, root_element)
  schema = Nokogiri::XML::Schema(File.read(schema_path))
  document = Nokogiri::XML(File.read(document_path))
  schema.validate(document.xpath("//#{root_element}").to_s)
end

v...

Deploy and migrate with a single Capistrano command

Note that this sounds good but is not good at all when hooking tasks on cap deploy (see this article). Make sure to hook your calls properly when using this.


To deploy an application and run all pending migrations before restarting it, you can use the following standard Capistrano task:

cap deploy:migrations

Little is known what happens when the deployment goes through, but a migration or a rake task aft...

Speed up file downloads with Rails, Apache and X-Sendfile

When you use the send_file method to send a local file to the browser, you can save resources on the application server by setting the :x_sendfile option to true. This option is activated by default for Rails 3, so you need to understand this.

What this option does is not to send any data at all, but rather set the local file path as a new response header:

X-Sendfile: /opt/www/awesome-project/shared/downloads/image.png

When the response comes back from Rails to...

remove_index fails silently for non-existing indexes in Rails 2 migrations

When you try to remove a non-existing index using remove_index, the migration will incorrectly pass without an error. The schema will not be changed, but the migration will be considered migrated.

Since this might be fixed in the future, you cannot mend your database by adding another migration on top of the faulty one. You should manually alter the database schema to the previous migration on all machines that migrated the faulty migration (inform your fellow developers), then delete the faulty migration from the repository.

OscarGodson/jKey - GitHub

jQuery plugin to register callback functions to keyboard shortkuts. Keyboard events in vanilla Javascripts are super-painful to work with, so hopefully this library can help.

Rails: When defining scopes with class methods, don't use `self`

Sometimes it is useful to define a named scope by implementing a static method with the scope's name on the scoped class. For instance, when a method should decide which existing scope should be the next link in the scope chain. Take this class for example:

class Meal < ActiveRecord::Base

  named_scope :for_date, lambda { |date| :conditions => { :date => date }}
  named_scope :with_meat, :conditions => { :meat => true }
  named_scope :without_meat, :conditions => { :meat => false }

  def self.suitable_for(user)
    if user.vegetar...

MySQL: "LOAD DATA INFILE" says "file not found"

This might be due to AppArmor denying the MySQL server access to most of the filesystem. You can instead use
LOAD DATA LOCAL INFILE ...
to pipe data through the MySQL client, which can read everything the executing user can.

Properly sanitizing column names for MySQL

There are times when you need to send SQL to the database, like this:

def self.some_count(field)
  field = connection.quote_column_name(field)
  scoped(:select => "COUNT(DISTINCT #{field}) AS count")
end

Although the given variable is sanitized here, the MySQLAdapter's (and probably other adapters as well) method for this is insufficient as it only wraps backticks around it, not helping against injection:

Klass.some_count("id`); DELETE FROM users; -- ")
# Will result in this SQL which is valid but definitely undesi...

How to define constants with traits

When defining a trait using the Modularity gem, you must take extra steps to define constants to avoid caveats (like when defining subclasses through traits).

tl;dr

In traits, always define constants with explicit self.

If your trait defines a constant inside the as_trait block, it will be bound to the trait module, not the class including the trait.
While this may seem unproblematic at first glance, it becomes a problem when including trai...

ETags with memcached

I love ETags, but there’s something that annoys me: most implementations revolve around pulling a record out of a data store and only “rendering” the response if it hasn’t been modified. 

The problem with this approach is that request has already gone through most of your application stack–parsing params, authentication, authorization, a few database lookups–so ETags are only saving you render time and some bandwidth.

While working on a Sinatra-based JSON web service that gets very heavy traffic, I wanted to find a way to short-circuit...

Always show the page if there is an error in Cucumber

Are you adding a "Then show me the page" and re-run Cucumber whenever there is a failing scenario? Don't be that guy!

Save time with the shiny new version of our cucumber_spinner gem. It comes with a Cucumber formatter that not only displays an awesome progress bar, and shows failing scenarios immediately, it will also open the current page in your browser whenever a scenario step fails.

After you installed the gem, use the formatter like this:

cucumber --format CucumberSpinner::Curiou...

Concurrency issues with find-as-you-type boxes

Find-as-you-type boxes are usually built by observing changes in a text field, and querying the server via AJAX for search results or suggestions when the field has changed.

A common problem with this implementation is that there is no guarantee that AJAX responses are evaluated in the same order as the original requests. The effect for the user is that the search results are flashing back and forth while the user is typing the query, and when the user has stopped typing the last results don't always match the final query.

Workarounds
----...

Speed up RSpec by deferring garbage collection

Update: This trick probably isn't very useful anymore in Ruby 2.x. The Ruby GC has improved a lot over the years.


Joe Van Dyk discovered that running the Ruby garbage collector only every X seconds can speed up your tests. I found that deferring garbage collection would speed up my RSpec examples by about 15%, but it probably depends on the nature of your tests. I also tried applying it to Cucumber f...

How to: Use git bisect to find bugs and regressions

Git allows you to do a binary search across commits to hunt down the commit that introduced a bug.

Given you are currently on your branch's HEAD that is not working as expected, an example workflow could be:

git bisect start # Start bisecting
git bisect bad # Tag the revision you are currently on (HEAD) as bad. You could also pass a commit's SHA1 like below:
git bisect good abcdef12345678 # Give the SHA1 of any commit that was working as it should
# shorthand:
git bisect start <bad ref> <good ref>

Git will fetch a comm...

Apache: Redirect all requests from one host to another

In order to redirect all requests from redirecting-host.com to desired-host.com while keeping path and query params unchanged, change your Apache VHost to something like this:

ServerName desired-host.com
ServerAlias redirecting-host.com
RewriteEngine On
RewriteCond %{HTTP_HOST} !^desired-host.com$
RewriteRule ^.*$ http://desired-host.com%{REQUEST_URI} [R=301,L]

Take care to keep all those ^, $ and ! as seen in the example.

Export CSV from MySQL directly

If you need to export data from MySQL to a CSV, you can profit from really fast built-in methods.

This query writes the data to /tmp/geodb_coodinates.csv. And it's fast: Query OK, 337925 rows affected (0.86 sec)

SELECT * INTO OUTFILE '/tmp/geodb_coordinates.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '\\' LINES TERMINATED BY '\n' FROM geodb_coordinates;