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.
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...
 
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.
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.
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.
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, notspec. - RSpec and rspec-rails have been completely refactored internally. All RSpec classes have been renamed from 
Spec::SomethingtoRSpec::Something. This also means that everyrequire 'spec/something'must now berequire 'rspec/something'. - In 
spec_helper.rb,Spec::Runner.configurebecomesRSpec.configure - It has become really hard to extend specific example groups ...
 
Shell script to quickly switch Apache sites
I prefer the application that I'm currently working on to be reachable at http://localhost/.
So when I switch to another project, I use this handy shell script to set one site as the current one. Call it just like this:
apache-site makandra-com
Note that it disables all other sites in your Apache configuration so you would not want to use this on production machines.
Furthermore it will also enable the default site if that was available.
When you call apache-site with no arguments, it will list all available sites.
...
On memoizing methods that return a scope
Be careful when memoizing a method that returns a scope, e.g.:
def variants
  scoped(:conditions => { :name => name })
end
memoize :variants
Because of the way memoize is implemented, that method now no longer returns a scope but its loaded target array.
The best solution is to use the Memoizer gem instead.
A workaround is to roll your own memoization:
def variants
  @va...
Working around the ancestry gem's way of object destruction
The ancestry gem allows you to easily use tree structures in your Rails application.
There is one somewhat unobvious pitfall to it: its way of applying the orphan_strategy which defines how it handles children of an object going to be destroyed.
What's this all about?
In many cases you might want to disallow destruction if there are any child nodes present. The restrict strategy does the trick but raises an exception when destroy is called:
has_ancestry :orphan_st...
Install the Nokogiri gem on Ubuntu servers
You need to install the following packages before you can build the Nokogiri gem:
sudo apt-get install libxml2-dev libxslt1-dev
Resolve Aspell errors with your Rails application
If you get an error message like that you are missing the Aspell files a specific language:
No word lists can be found for the language "de"
Solve it by installing the proper package, e.g. on Ubuntu:
sudo apt-get install aspell-de
apotonick's hooks at master - GitHub
Hooks lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as you run the hook.
Even with bundler your gem order can be significant
Even when you're using bundler, it might be significant in which order your gems are listed in your Gemfile. This can happen when gems are running around calling require or require_dependency on other gems or application classes when loaded (don't do that!).
A known culprit of this is the (otherwise wonderful) resource_controller gem, which requires ApplicationController when loaded. When your ApplicationController requires later-loaded gems when loaded, Rails will not boot.
He...
An obscure kernel feature to get more info about dying processes
This post will describe how I stumbled upon a code path in the Linux kernel which allows external programs to be launched when a core dump is about to happen. I provide a link to a short and ugly Ruby script which captures a faulting process, runs gdb to get a backtrace (and other information), captures the core dump, and then generates a notification email.
Inline if-then-else in MySQL queries
It can be useful to have a Ruby expression like condition ? positive_case : negative_case in MySQL queries:
UPDATE users SET monthly_debit = IF(subscriber, 19, 0)
Precedence of Ruby operators
[ ] [ ]=**! ~ + -* / %+ ->> <<&^ |<= < > >=<=> == === != =~ !~&&||.. ...? := %= { /= -= += |= &= >>= <<= *= &&= ||= **=defined?notor andif unless while untilbegin/end
For more information see Table 18.4 in The Pragmatic Programmer's Guide.
Generate a strong secret from the shell
A good tool to generate strong passwords and secrets is "apg". You can get it with
sudo apt-get install apg
To create a strong secret for sessions, hashed Paperclip paths, etc. say
apg -m128 -a1 -E\'\"
Arguments explained:
- The 
-mparameter defines the secret length - 
-a1makes apg choose from all 7-bit ASCII characters instead of just the alphabet - 
-E\'\"excludes quote characters so you can easily paste the secret into a Ru... 
jsmestad's pivotal-tracker at master - GitHub
Ruby gem that provides an AR-style interface for the Pivotal Tracker API.