Mailcatcher: An alternative to inaction_mailer

Looks simpler than inaction_mailer:

gem install mailcatcher
mailcatcher

Setup Rails to send mails to 127.0.0.1:1025. Usually you want the following config in config/environments/development.rb and maybe in test.rb or cucumber.rb.

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => 'localhost',
  :port => 1025
}

Now you can see sent mails in your browser when opening http://127.0.0.1:1080

Note: In order to s...

How to change the order of nested forms being rendered (especially blank forms)

Generally for nested forms, a blank form is placed below all other existing object forms. If you would like to change the position of the blank form(s) you can reorder the object's one-to-many association. For example you can put the blank form on top with the following snippet:

actors = movie.actors
actors.build
actors.unshift(actors.pop(1)) # won't work with Rails 4+

Because build_for_form creates new objects and ap...

Git: Change author of a commit

Using git rebase can be painful but luckily you can resort to cheating with git reset and committing anew.
Now what if you wanted to rebase commits of other people and still wish them to be the authors of their code? Easy: make them the author of a commit you made.

When you have freshly staged changes that are ready to be committed, just use the --author switch:

git commit -m "Hello Universe" --author="Philip J Fry <someone@example.com>"

If...

Removing ANSI color codes from Rails logs

The colors in Rails log files are helpful when watching them but, since they are ANSI color codes like ^[[4;36;1m, can be annoying when you are reading the logs with a tool that does just prints those control characters (like less or vim).

Remove them with sed:

cat staging.log | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]//g"

This will print the log without colors to your terminal. You can pipe the result into less for example.

To have a file you can vim around with, just write that output into a new file:

ca...

Usage of RSpec's raise_error

Never use raise_error without specifying the Error you expect.

expect { do_a_lot_of_complicated_stuff }.to raise_error

will be green if you make any error in programming. E.g. a simple typo would make the test above green. The block will catch the Spec:: exception and the test will be happy.

Be sure to always have custom errors in your models and raise them in a manner that lets you know what went wrong.

expect { execute_payment! }.to raise_error(PayPal...

Test that a form field has an error with Cucumber and Capybara

You can use the step definition below to say this:

Then the "Last name" field should have an error

Capybara

Then /^the "([^\"]*)" field should( not)? have an error$/ do |field, negate|
  expectation = negate ? :should_not : :should
  page.send(expectation, have_css('.field_with_errors', :text => field))
end

MySQL: For each group, retrieve a comma-separated list of values in a given column

The technique described in this card has an important caveat: The result of GROUP_CONCAT is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. This will cause horrible, data-destroying bugs in production. For this reason you should probably not use GROUP_CONCAT ever. At least you must set the value of group_concat_max_len to an insanely high value on every database server your application runs on.


Lik...

Using heredoc for prettier Ruby code

You can use heredoc to avoid endlessly long lines of code that nobody can read. Heredoc strings preserve linebreaks and can be used like this:

def long_message
  puts(<<-EOT)
    Here goes a very long message...
    Sincerely,
    foobear
  EOT
end

<<-EOT will be somewhat of a placeholder: anything you write in the line after you used it will be its value until you write EOT in a single line.

You can use any string to flag your heredocs. To be more verbose you...

Change / Update SSL certificate for Amazon Elastic Load Balancer

There is a new card about how to do this with the new AWS Command Line Interface


At first you need the IAM Cli Tools.
-------------------------------------------------------------------------------------------------------------...

Disable output when using cURL

cURL makes a web request and shows you the response body.

You can redirect the response body to /dev/null just like for many other programs. But if you do that, cURL will display some short information about the request you are making:

$ curl http://www.example.com/ > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 30865  100 30865    0     0   4793      0  0:00:06  0:00:06 --:--:-- 10199

If you wan...

Make an HTTP request to a machine but fake the hostname

Consider you have a website vhost listening to www.example.com, redirecting all incoming requests that do not talk about the configured hostname (this is often used to redirect users to http://www.example.com when entering only http://example.com/).

If you want to make a request to that site's web server without actually talking to www.example.com (e.g. because this is a load balancer's address but you want to access one specific machine), you cannot just request machine1.example.com or localhost as the above vhost will redirect...

"Address already in use" with autossh

If you get an error "Adress already in use" with autossh check with lsof or netstat if something already listen on the Ports you want to use.

There are three Ports you have to look at. If your Command look like this:

/usr/local/bin/autossh -f -M 5100 -g -N -C -L 8080:127.0.0.1:80 example.com -i ~/.ssh/id_rsa -l user

The following three ports need to be available:

  1. 8080: The Port you want the tunnel to listen
  2. 5100: The Autossh Monitoring Port
  3. 5101: Autossh also uses the Monitoring Port +1

How to install a frozen version of Firefox for your Selenium tests

Whenever Firefox updates, all your Cucumber features that use Selenium break. This is annoying.

In order to remedy this, version 0.5.0 of our geordi gem comes with a script that helps you create an unchanging version of Firefox for your Selenium tests. In particular, this new copy of Firefox will have the following properties:

  • It won't update itself with a newer version
  • It can co-exist with your regular Firefox installation (which you can update at will)
  • It will use a profile separate from the one...

Compose a regular expression from other RegExp objects

You can create a Regexp object from existing Regexp objects by using the interpolation syntax you know from strings:

re1 = /x/
re2 = /a#{re1}b/
'aaxbb' =~ re2 # => 1

Note

If your regular expression contains backreferences like \1, they may no longer refer to the correct capture group after concatentation.

Machinist's #make breaks on has_many associations when defining method `empty?`

Observed on Rails 2.3 and machinist 1.0.6

Like the title says, when you define the method empty? like in the following example, you may not longer use collection.make.

class Book

  has_many :pages

  def empty?
    pages.empty?
  end

end

Assuming

b1 = Book.find(1)
b2 = Book.find(2)

instead of expected

b1.pages.make #=> #<Page id: 1, book_id: 1>
b2.pages.make #=> #<Page id: 2, book_id: 2>

you'll get

b1.pages.make #=> #<Page id: 1, book_id: 3>
b2.pages.make #=> #<Page id: 2,...

dbconsole in Rails 3 requires the environment as the first argument

There is a bug in Rails 3's dbconsole script, which makes the following command open a database console for the development environment:

rails dbconsole -p test

You need to write this instead:

rails dbconsole test -p

Invoices: How to properly round and calculate totals

While it might seem trivial to implement an invoice that sums up items and shows net, gross and vat totals, it actually involves a lot of rules and caveats. It is very easy to create invoices where numbers don't add up and a few cents are missing. A missing cent is a big deal for an accountant, so it is important for your invoices to list correct numbers.

Note that this is not legal advice. Also note that while this note has a number of code examples in Ruby and MySQL, the concepts apply to all programming languages and data stores.

When ...

Always show all form errors during development

You've been there: A form cannot be submitted, but you don't see a validation error because the field at fault has no corresponding input field on the form. Because this is usually a bug, you insert debug information listing all errors into the form view. And once the bug is fixed, you forget to take out that debug information.

There is a better way. By copying one of the attached initializers into config/initializers, your forms will always render a small box listing all form errors in the bottom right corner of the screen. This box is n...

Webrat doesn't follow redirect because it considers the url external

Rails doesn't know which host it is running on. For generating links, it strips the hostname off the request URL, which can lead to errors when you have absolute URLs in your Cucumber tests.

If you really need to use absolute URLs somewhere, say in an email you send, either throw away the host when parsing it (e.g. body.scan(/http:\/\/[^\/]+\/([^\s"<]+)/)) or tell Webrat you're back on your site.

Downgrade Firefox 6 to Firefox 5 on Ubuntu

Note that if you plan to downgrade Firefox because your Selenium tests broke after a Firefox upgrade, there is a better way that doesn't involve downgrading. Mozilla has stated that they will no longer provide security patches for any but the most recent versions of Firefox. So running an old Firefox should not be a long-term solution for anything.

If you still want to downgrade your Firefox for other reasons, here is how I downgra...

Prevent your Firefox from auto-updating

Note that if you plan to freeze your Firefox versions because your Selenium tests break whenever Firefox updates, there is a better way that lets you keep an up-to-date Firefox. Mozilla has stated that they will no longer provide security patches for any but the most recent versions of Firefox. So running an old Firefox should not be a long-term solution for anything.

If you still wish to disable the auto-update in Firefox, a poste...

Distance of time in what you like: days, months, years

Sometimes the Rails helper #distance_of_time_in_words is using too much magic.
When you need a time difference in a specific unit, use this method:
^
def distance_of_time_in(unit, from, to)
diff = to - from

  if 1.respond_to? unit
    distance = diff / 1.send(unit)
    distance.abs.round
  else
    raise ArgumentError, "#{unit.inspect} is not supported as unit"
  end
end

distance_of_time_in(:days, Time.now, 1.year.ago)
=> 365

Remove the .abs if you want the mathematical *differ...

List sizes of MySQL databases

Do you wonder which databases are actually taking up how much space but only have one huge ibdata1 in your /var/lib/mysql and the directories inside your mysql data directory don't represent the actual database sizes? This is for you!

Run from a mysql root console:

SELECT table_schema AS "Database name", SUM(data_length + index_length) / 1024 / 1024 AS "Size (MB)" FROM information_schema.TABLES GROUP BY table_schema;

This will get you a result like the following:

+----------------------+--------------+
| Database name    ...

Fix: FreeBSD is not able to connect to the network

This article from the FreeBSD Handbook suggests that editing /etc/rc.conf enables DHCP. Unfortunately, some times this seems not sufficient.

Try a reboot, or start the DHCP client manually with the command

dhclient <network adapter>

You can find a list of network adapters by running ifconfig. Examples are em0 or lo0.