Take care when merging with params

Be careful when using params.merge as params is a HashWithIndifferentAccess.

Why?

Usually this should not be an issue but it turns crazy if you try to include associated models deeper than 1 level:
options = params.merge(:include => { :user => :avatar })
Post.paginate options

When inspecting the merged params you will get something like this:
{ :include=> { "user" => :avatar }, :page => 23 }

Here the :user symbol in the hash of inclusions turned into a "user"...

Use form_for without the enclosing form tag

Need form builder helpers without emitting a surrounding <form> tag, for partial updates such as XHR-driven field changes. Rails fields_for yields the same builder without hidden inputs or authenticity token.

Shell script to quickly switch Apache sites

Quickly make one Apache virtual host available at localhost while switching projects. The script disables other sites, can re-enable the default site, and lists available sites without arguments.

On memoizing methods that return a scope

Memoizing a scope-returning method can turn the scope into a loaded array, breaking lazy query chaining; a safer memoizer or manual instance-variable cache avoids it.

Generate a path or URL string from an array of route components

polymorphic_path and polymorphic_url build route strings from arrays of model objects or route components, including :new and :edit prefixes. Nested Active Record namespacing can fail to resolve the correct route.

Adding a Timepicker to jQuery UI Datepicker

The timepicker addon adds a timepicker to jQuery UI Datepicker, thus the datepicker (jQueryUI) is required for using any of these. In addition all datepicker options are still available through the timepicker addon.

Falsehoods Programmers Believe About Names

I’m going to list assumptions your systems probably make about names. All of these assumptions are wrong. Try to make less of them next time you write a system which touches names.

Getting your e-mails back after upgrading Thunderbird to version 3

If you previously used version 2.x of Thunderbird and upgraded to 3.x (for example through an Ubuntu release upgrade) you might notice that Thunderbird will not show any of your old e-mails or settings.

This results from a different directory being used for storing profiles and configuration.

You can replace the blank profile with your old one like this:
cd ~
mv .thunderbird .thunderbird-invalid
cp -R .mozilla-thunderbird .thunderbird

Upon its next start, Thunderbird brings up the migration wizard introducing you to a few vers...

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...

Inspecting model callback chains

Rails models expose callback chains for save events, making it possible to inspect registered before and after methods and identify method names.

Find the newest file from shell

Get the most recently modified file in a directory for shell script processing using ls -1tr and tail -1.

Force RubyMine to notice file system changes

RubyMine may lag behind file operations done outside the IDE, leaving the project tree and file list stale. sync or File → Synchronize forces an update.

Setting nil values in Machinist blueprints

Blueprint attributes in Machinist can keep inherited values unless nil is wrapped in a block; editor { nil } clears the master value, plain nil does not.

Dealing with ActiveRecord::RecordNotSaved

ActiveRecord::RecordNotSaved often comes from a callback method returning false, especially when the last assignment is boolean. Ending the method with true avoids the save being aborted.

Here’s what we’ve learned about doing UI for mobile web apps with WebKit

Lately, we’ve been exploring ways to offer web apps that perform like native apps on mobile devices. For this short sprint we targeted mobile WebKit browsers—especially the default browsers on iOS and Android—because of their widespread use and excellent support for HTML5 and CSS3. Here are a few things we’ve learned along the way.

Match strings in a given order with Cucumber and Capybara

Verify that page text appears in a specific sequence while ignoring HTML markup, using a Cucumber step for plain-text order checks.

Preload tags with acts-as-taggable-on

When you do tags with acts-as-taggable-on and want to preload associated tags, you can do so with

TaggedModel.scoped(:include => :tag)

Note however that this will only prevent tagged_model.tags from hitting the database. Using tagged_model.tag_list does not use the preloaded association.

Solve ActiveRecord::MissingAttributeError "missing attribute: foo"

ActiveRecord::MissingAttributeError appears when a query omits a column later accessed on the model, often after using select with too few fields.

Using SSL in Rails 3

SSL in Rails 3 is non-obvious.

Machinist: Refer to another named blueprint inside a blueprint

Named Machinist blueprints can reuse another blueprint’s fields, letting variants combine shared defaults without repeating attribute definitions.

Be careful with Array(...)

Array(...) is a convenient coercion in Ruby, but to_a can split strings and trigger unexpected conversions for non-array inputs.

Deliver Paperclip attachments to authorized users only

Private Paperclip downloads need restricted storage or hashed URLs to keep attachments away from public access. A controller-based delivery path or secret-based paths reduce exposure.

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