How to install a specific version of RubyGems (and how to downgrade)

Sometimes you want one distinct version of RubyGems to be installed to replicate the same behavior across multiple servers.

Usually would do this to update your RubyGems, but this always takes you to the latest version:

gem update --system

While there are ways around the interwebs that use the rubygems-update package and call its setup.rb, there is an undocumented switch you can use:

gem update --system 1.3.7

This updates to the given version, 1.3.7 in the above case, by walking the rubygems-update package way itself.

---...

Geordi 1.9 released

New features:

geordi delete_dumps [directory]

Recursively search for files ending in *.dump and offer to delete those. When no argument is given, two default directories are searched for dump files: the current working directory and ~/dumps (for dumps created with geordi).

geordi drop_databases

Delete local MySQL/MariaDB and Postgres databases that are not whitelisted.

Authentication is handled via PAM for Postgres and MariaDB, via .my.cnf with fallback to mysql -p for MySQL. Different connection methods can be chosen via ...

Execution of shell code in Ruby scripts

Deprecated ways to execute shell code in Ruby

This is just a reference for legacy code. For new code, always use capture3.

%x{ } or backticks – quick and easy

Returns the standard output of running the given command in a subshell. This is an alias for `...`, and you can use string interpolation.

Example:

name = 'ls'
result = `which #{name}`

It does not escape anything you inject in the string, so be aware of possible security vulnerabilities...

Installing Adobe Reader on Ubuntu

Adobe no longer supports their PDF reader on Linux and the official page does not offer it for download. \
However, some files may not display properly on Ubuntu's default PDF reader Evince or PDF forms may not work as expected. Hence, you may still need to use it.

Here is how to install the Adobe Reader (acroread) if you need to:

  1. Download the .deb archive from the Adobe servers (yes, it's still there):

    cd /tmp && wget http://ardownload.adobe.com/pub/adobe/reader/unix/9.x/9.5.5/enu/AdbeRdr9.5.5-1_i386linux_enu.deb
    
  2. I...

terminator keyboard shortcuts

When connecting to multiple (i.e. > 4) servers to dive into logfiles or do security updates, terminator is what you want.
There are several keyboard shortcuts available:

  • Ctrl-Shift-E: Split the view vertically.
  • Ctrl-Shift-O: Split the view horizontally.
  • Ctrl-Shift-P: Focus be active on the previous view.
  • Ctrl-Shift-N: Focus be active on the next view.
  • Ctrl-Shift-W: Close the view where the focus is on.
  • Ctrl-Shift-Q: Exit terminator.
  • Ctrl-Shift-X: Enlarge active window...

HTML5: Allow to choose multiple files with a vanilla file picker

Modern browsers natively suppport file pickers that allow the user to choose multiple files at once. To activate this feature, set the multiple attribute:

<input type="file" name="images[]" multiple />

Or in a Rails view:

<%= file_field_tag "images[]", multiple: true %>

This works in IE10+.

Make sure that the field name ends in [] so your server-side code will parse the incoming files into an array. Obviously this naming convention is not compatible with default Rails nested attribute setters, so you'll need to write a form ...

Gherkin: Error during installation

When trying to install the gherkin gem, you might encounter an error with the following lines:

ERROR:  Error installing gherkin:
	ERROR: Failed to build gem native extension.
...
checking for main() in -lc... yes
creating Makefile
...
cc1: all warnings being treated as errors
Makefile:150: recipe for target 'gherkin_lexer_ar.o' failed
make: *** [gherkin_lexer_ar.o] Error 1
...

If upgrading is not an option, configure build options for gherkin:

bundle config --local build.gherkin --with-cflags=-w

Your .bundle/config fi...

Select a random table row with ActiveRecord

Use this scope:

class Stick
  named_scope :shuffled, lambda {
    last_record = last
    { :conditions => [ 'id >= ?', rand(last_record.id) ] } if last_record
  }
end

You can now pick a random stick by saying

Stick.shuffled.first

Or, if you prefer something smaller:

class Stick
  named_scope :shuffled, :order => 'RAND()'
end

Note however that you should never order by RAND() on tables that may become large some day, as this performs horribly and can kill your database server.

Offtopic: Floppy-disc OS

MenuetOS is an Operating System in development for the PC written entirely in 32/64 bit assembly language. Menuet64 is released under License and Menuet32 under GPL. Menuet supports 32/64 bit x86 assembly programming for smaller, faster and less resource hungry applications.

  • Fits on a single floppy, boots also from CD and USB drives
  • Responsive GUI with resolutions up to 1920x1080, 16 million colours
  • Free-form, transparent and skinnable application windows, drag'n drop
  • SMP multiprocessor support with currently up to 8 cpus
  • IDE: E...

Caching may break relative paths in your merged stylesheet

If you turn on stylesheet caching, it might happen that stylesheets from different locations with different relative pathes will be put together to one big stylesheet.

This stylesheet then resides in /stylesheets but still holds the old pathes, which aren't valid anymore. This leads to the effect that images are displayed on your local development machine (where caching is turned off automatically) but not on the server.

To fix this, either:
^

  • Move all stylesheets to the same folder
  • or have one cache per folder

Cast a string to the type of an ActiveRecord attribute

ActiveRecord models know how to cast a given string to the type of a given attribute (or column).

The following model will serve as our example:

create_table :notes do |t|
  t.string :title
  t.integer :user_id
  t.boolean :deleted
end

You can make the Note class cast strings into their respective types like this:

Note.columns_hash['user_id'].type_cast('123') # => 123
Note.columns_hash['deleted'].type_cast('1') # => true
Note.columns_hash['deleted'].type_cast('0') # => false

Getting started with Chef

Before installing chef, make sure curl is installed and sudo finds your gems

#Important

  • execute all commands from within your chef-repo directory, else you'll be missing out on configuration files

One cause for "iptables: No chain/target/match by that name" on Ubuntu

I couldn't successfully execute a simple iptables command and got this error on an Ubuntu server:

# /sbin/iptables -I INPUT ....
iptables: No chain/target/match by that name

The cause was that two modules weren't loaded: xt_multiport and xt_comment. Normally Ubuntu loads them automatically, but not this time due to another problem.

Rails 3.1 error message: Could not find a JavaScript runtime

After starting the Rails server in a freshly generated Rails 3.1 project you could see an error message such as

/usr/lib/ruby/gems/1.8/gems/execjs-1.3.0/lib/execjs/runtimes.rb:50:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

Just add a JavaScript runtime to your Gemfile and the error vanishes.

Examples:

gem 'therubyracer'
gem 'extjs'

XHR is not JSON

When a Rails controller action should handle both HTML and JSON responses, do not use request.xhr? to decide that. Use respond_to.

I've too often seen code like this:

def show
  # ...
  if request.xhr?
    render json: @user.as_json
  else
     # renders default HTML view
  end
end

This is just plain wrong. Web browsers often fetch JSON via XHR, but they (should) also send the correct Accept HTTP header to tell the server the data they expect to receive.

If you say request.xhr? as a means for "wants JSON" you are ...

Git instaweb

Git has a built-in repository viewer for your web browser. a bit similar (but less awesome) than github.

If you have apache installed, simply go to your repository, and enter
git instaweb --httpd apache2
otherwise, simply install lighttpd and just run
git instaweb

This should open a brower automatically pointing to your repository. If not, try to connect to localhost:1234.

You can stop the server with
git instaweb --stop

Defining "partials" in pure HTML without additional rendering helpers

A while ago I tweeted a thread about how a small JavaScript snippet, one that can fit in a single tweet in fact, can be used to allow defining custom elements purely in HTML. This post will expand on the idea, show how the snippet works, and argue for why you might want to actually use this.

A nice trick that lets you define "partials" in HTML without any additional rendering technology on the server or client.

Refile: Ruby file uploads, take 3

Jonas Nicklas, the author of Carrierwave and Capybara, has released Refile, a gem for handling file uploads in Rails. It handles direct uploads (also direct uploads to Amazon S3) better than Carrierwave.

The story and reasoning behind some of the decisions in Refile, and how it's different from Carrierwave, by the author himself, is a good read before deciding which way you'll go.

Big Caveat: Refile only stores the original image and r...

How Exchange handles multipart/alternative emails

In Rails, you can very easily send emails with HTML and plaintext bodies.

However, if you're trying to debug those using your normal email account, you might be out of luck: For some reason, Exchange servers will simply throw away the plaintext part of your mail, and just save the html part.

Mysql/Mysql2 agnostic database.yml

If you upgrade to the mysql2 gem, you will run into the problem that the server's database.yml (which is usually not under version control) needs to change exactly on deploy.

You can however make your database.yml work for mysql and mysql2 at the same time. Simpy do this

production:
   adapter: <%= defined?(Mysql2) ? 'mysql2' : 'mysql' %>
   #...

Using Firebug Lite to inspect HTML in Internet Explorer and other browsers

You know Firebug as a Firefox extension but there is also a "Lite" version which runs purely off JavaScript.

Though all major browsers offer inspection tools you may like the Firebug style. Also, for me this is a lot better than the IE8 developer tools -- and it works in older versions of IE, too.

Get the bookmarklet over at http://getfirebug.com/firebuglite#Stable. It usually loads the JavaScript code from a remote server but you can also download it to have it run locally. If adding the bookmarklet does not work in IE, add a new book...

VirtualBox host IP address and hostname

When you are using NAT in your virtual machine (which you should), the host's IP address is:

10.0.2.2

You'll need it to access shared folders or your host's web server when testing pages in IE.

Fun fact: You could also use vbox.srv -- that's the corresponding hostname.

pgAdmin has a "graphical EXPLAIN" feature

When working with PostgreSQL, you can use pgAdmin as a GUI.
While you can do most things just like on an SQL console, you can use it to display EXPLAIN results in a more human-readable way.


(image from the Postgres manual)

  1. Open up pgAdmin, connect to your server
  2. Pick a database from the left pane
  3. Click the "SQL" icon in the toolbar, or press Ctrl+E to open the query tool.
  4. Paste any queries that you'd like to explain.
  5. Go to "Query" → "Explain analyze", or ...

Cucumber: More patience for Selenium features

When running Selenium features with parallel_tests, some browser-server interaction might take longer than usual and the impatient Capybara will not wait enough to see results.

Put the attached file into features/support/ to make Capybara more patient in scenarios tagged @javascript.