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
If you need to look at the list of methods that are called upon certain events (like before/after saving etc), do this:
Model._save_callbacks.select {|cb| cb.kind == :before}.map{ |c| c.instance_variable_get :@filter }
Rails 2
User.after_save_callback_chain
To look at the method names only, you could do something like that:
User.after_save_callback_chain.collect(&:method)
Find the newest file from shell
This can be helpful when you need the latest file inside a directory for processing in a shell script:
ls -1tr * | tail -1
Used switches
The -1
switch makes ls
return 1 file per line, -t
orders by modification time and -r
causes sorting from oldest to newest. tail -1
then returns the last line, containing the newest file's name.
If you require only a subset of files, adjust the "*
" mask accordingly or use other switches of ls
.
Force RubyMine to notice file system changes
If you did file operations inside a shell or for example using Nautilus, it can take quite a while until RubyMine takes note of them and updates things like your project tree or its internal file list.
Flushing file system buffers helps you out (run it from a terminal):
sync
This is also possibly via the RubyMine menus: File → Synchronize.
Setting nil values in Machinist blueprints
Take care when trying to set attributes to nil
in a blueprint.
Given the following master blueprint:
Story.blueprint do
title
author { User.make }
editor { User.make }
end
This approach will not overwrite/remove the editor
defined in the master blueprint:
Story.blueprint(:draft) do
editor nil
end
...whereas this one will (note the lambda):
Story.blueprint(:draft) do
editor { nil }
end
Dealing with ActiveRecord::RecordNotSaved
If you get an ActiveRecord::RecordNotSaved
error, a method inside one of your model's callback chains (before_save
etc) possibly returned false.
This commonly happens when you have a method setting attributes and the last one is a boolean set to false (as the value of the last statement is returned). Fix this by simply calling true
at the end of such methods:
def hide
self.visible = false
true
end
Note that nil
won't cause this behavior. Thus, you can use an if
without problems -- if you are not returning fal...
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
Sometimes the order in which strings appear on a page matters to you.
Spreewald gives you steps like these:
Then I should see in this order:
| Alpha Group |
| Augsburg |
| Berlin |
| Beta Group |
Or, if you prefer multiline strings:
Then I should see in this order:
"""
Alpha Group
Augsburg
Berlin
Beta Group
"""
The step ignores all HTML tags and only tests on plain text.
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"
Did you use the :select
option in a find
, and forgot to include foo
?
Machinist: Refer to another named blueprint inside a blueprint
Note: We are talking about Machinist 1 here, Machinist 2 may have solved this or might require a different approach.
Machinist allows named blueprints (e.g. User.blueprint(:admin)
) that inherit from the master blueprint (User.blueprint
).
If you also want to inherit from another blueprint (e.g. if "vip" should load "premium" and the master blueprint) you can do this:
User.blueprint(:vip) do
# Fields for the vip blueprint go her...
Be careful with Array(...)
A popular ruby idiom I keep stumbling upon is
def do_some_thing_for(values)
values = Array(values)
values.each { ... }
end
The intent is to allow the user to pass in arrays as well as scalar values, since
Array("foo") == ["foo"]
Array(["foo", "bar"]) == ["foo", "bar"]
But Array()
actually calls to_a
on its arguments, which may not always do what you expect. For example
Array("foo \n bar") == ["foo \n", "bar"]
Deliver Paperclip attachments to authorized users only
When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.
- Deliver attachments through Rails
The first way is to store Paperclip attachments not in the default public/system
, but in a private path like storage
inside the current release. You should prefer this method when dealing with sensitive data.
Make ...
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
Prevent SSH from timing out
If you have problems with SSH session timing out, add the following to your /etc/.ssh/config
:
Host *
ServerAliveInterval 55
ServerAliveCountMax 2
Using the full power of have_css
Capybara's has_css?
matcher has a couple of options you might find useful.
Check that a selector appears a given number of times
Use the :count
option like this:
Then /^I should see (\d+) users?$/ do |count|
page.should have_css('ul#users li', :count => count.to_i)
end
Check that a selector has a given text content
Use the :text
option like this:
Then /^I should see a user with name "([^\"]*)"$/ do |nam...
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)