How to deal with MethodNotAllowed errors

One of the most common production errors are ActionController::MethodNotAllowed errors. They usually happen when someone reloads a form by pressing enter/return in the URL field, or by opening JavaScript links incorrectly.

The attached initializer provides a default way to deal with this.

You'll get the following behaviour:

  • if the incorrect request has a HTTP_REFERER coming from the same application, set a flash, and redirect back
  • if the incorrect request has no HTTP_REFERER or one coming from an external source, set a flash...

Useful script to collect downloads from several sites

For university I have to stay up-to-date with lecture documents. Since my university doesn't offer RSS feeds, I wrote a little script that collects files from web pages.

You want this, if you have several web pages that offer downloads that you don't want to check manually. Just register the URL and a CSS snippet to retrieve the files in the attached script and run it – it will fetch all your files. It will store all files in a single place or sort them into respective directories.

Edit the header of the file (providing your data), save it...

Request a gzipped response from a web server using Wget

To reduce download time, application servers usually serve content using gzip compression, if the browser supports it.

When using a tool like Wget to explicitly download an application's response, the server responds with the uncompressed version:

wget http://example.com/

If you are curious about the compressed file's size, pass the corresponding HTTP header:

wget --header="accept-encoding: gzip" http://example.com/

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

How to ignore new files or changed files in git

How to ignore new files

Globally

Add the path(s) to your file(s) which you would like to ignore to your .gitignore file (and commit them). These file entries will also apply to others checking out the repo.

Locally

Add the path(s) to your file(s) which you would like to ignore to your .git/info/exclude file. These file entries will only apply to your local working copy.

How to ignore changed files (temporarily)

In order to ignore changed files to being listed...

Declare different CSS background-images for different locales

If you would like to use language specific layout (e.g. background-images) in your applications stylesheets you can achieve this easily by using the lang attribute in your views (ERB):

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= I18n.locale || 'en' %>" lang="<%= I18n.locale || 'en'%>">
...
</html>

or in HAML:

%html :xmlns => "http://www.w3.org/1999/xhtml", :"xml:lang" => I18n.locale || 'en', :lang => I18n.locale || 'en'

Then, in your stylesheet you can for example declare different background-images fo...

Web font embedding requires new CSS for IE9

If you embedded web fonts in the past years (e.g. by copying CSS from a Font Squirrel @font-face kit), that CSS won't work in Internet Explorer 9.

You can fix it by turning these styles...

@font-face
  font-family: 'MyFont'
  src: url('myfont.eot')
  src: local("☺"), ('myfont.ttf') format("truetype")
  font-weight: normal
  font-style: normal

... into these:

@font-face
  font-family: 'MyFont'
  src: url('myfont.eot')
  src: local("☺"), url('myfont.e...

How the Clearance gem remembers and clears sessions

Clearance is a gem that provides authentication functionality (e.g. login, logout). This note explains, how the clearance login, logout and (in old Clearances) remember me functionality works.

Login

Clearance defines a database column called "remember_token". When you login in, that token will be saved in a cookie. For that reason you don't have to re-sign-in when you close and open the browser again.
This also means that you can be logged in in more than a single browser. Also see [When ses...

Improve web font rendering in Windows by autohinting fonts

Web fonts are awesome. After being restricted to Arial for two decades there is finally a cross-browser way to embed fonts into web pages.

Unfortunately while web fonts look awesome on Linux and MacOS, they look horrible on Windows, a problem that gets worse with smaller font sizes.

The culprit is something called font hinting:

...

Creating a patch in git and how to apply patches

You can convert git commits into patch files. Those can be used to apply to a different repository [1] or by someone else (e.g. sent when sent to them via e-mail).

Creating a patch in git


  1. Make your changes and commit them.
  2. Run git format-patch COMMIT_REFERENCE to convert all commits since the referenced commit (not including it) into patch files.

For example, let's say you prepared 2 commits. Run:

git format-patch HEAD~~ 

This will create 2 files, one for each commit since HEAD~~, like these:

00...

Stub a request's IP address in a Cucumber scenario

The solution in this card is based on a stack overflow post by Leventix.

If you need to make request come from a fixed IP address for the duration of a Cucumber scenario, the code below lets you write this:

Given my IP address is 188.174.117.205

Rails 3

Given /^my IP address is "(.*?)"$/ do |ip|
  ActionDispatch::Request.any_instance.stub(:remote_ip).and_return(ip)
end

Rails 2
-----...

Parse & sort unique hits in logfiles

If you want to know the exact hits on your website (or whatever logfile you want) for a specific date without duplicates, here's how.
"Unique" means you don't want to count hits to an URL originating from the same IP twice.

You can use the attached script to do so:

# ./log_parser.rb 2011-10-04

27 hits on /rss.xml
36 hits on /stylesheets/fonts/slkscr-webfont.woff
37 hits on /stylesheets/fonts/slkscrb-webfont.woff
37 hits on /images/bullet.png
38 hits on /images/download.png
38 hits on /images/play.png
39...

Rails logs are not flushed automatically (in Rake tasks)

The Rails logger will store its content in a buffer and write it into the file system every 1000 lines. This will come back to bite you when using Rails.logger.info to write log output during Rake tasks or on a production console.

You often won't notice this because for the development and test environments auto_flushing is set to write after each line. On production environments the Rails logger writes only every 1000 lines -- and not upon shell or script ter...

Monitor a Rake task with God

In order to monitor a Rake task using God your Rake file must write a file with its process ID (PID) to a path determined by God. This way God can check whether the Rake process is still alive.

Here is how to do this: In your God config, call the Rake task with an environment variable PIDFILE. This variable should equal the PID file path desired by God:

God.watch do |w|
  w.dir = "#{rails_root}"
  w.name = "my_task"
  w.interval = 10.seconds
  w.pid_file = "#{rails_root}/tmp/pids/#{w.name}...

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

Fixing "Lock obtain timed out: SimpleFSLock" for Solr

If your application raises an error like ...
Couldn't connect to the Solr server at http://127.0.0.1:8983/solr. 500 "Lock_obtain_timed_out_SimpleFSLock(...)"

... and if your jetty.request.log contains entries such as ...
127.0.0.1 - - [13/09/2011:12:42:23 +0000] "POST /solr/update HTTP/1.1" 500 4412
127.0.0.1 - - [13/09/2011:13:37:03 +0000] "POST /solr/update HTTP/1.1" 500 4309

... you probably have a lucene-...-write.lock file lying around in your Solr data directory that is not being cleaned up properly. This causes...

Dragging a file into your terminal pastes the file path

When you drag a file from a Nautilus window into a terminal window, the file's path will be pasted into the terminal. This also works with multiple files.

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

Turn off SSL for scenarios with Selenium

Selenium does not speak SSL because it uses WEBrick that doesn't. When you use Selenium for Cucumber scenarios that visit pages with SSL, they will fail.

To turn off SSL only for scenarios that are executed on WEBrick, put this method into your application controller.

def ensure_proper_protocol
  request.headers['SERVER_SOFTWARE'].andand.include?('WEBrick') || super
end

Let a Rails 3 application make a request to itself

Ever wondered how Rails talks to itself in a Cucumber feature? In Rails 3 you can do it like this:

def rack_env(path)
  { "rack.input" => {},
    "PATH_INFO"=>"#{path}",
    "REQUEST_METHOD"=>"GET" }
end

request = rack_env('/users/new')
response = Rails.application.call(request)
status, headers, body = response

puts status # e.g. 200
puts headers.inspect # hash of headers
puts body.body # html of response body

Instead of Rails.application you can also call any Rack application.

How to use Rails URL helpers in any Ruby class

If you have any class which requires access to some path methods generated by your routes. Even though you could technically include Rails.application.routes.url_helpers, this may include way too many methods and even overwrite some class methods in the worst case.

Instead, most of the time the following is advised to only make the desired methods available:

class Project
  delegate :url_helpers, to: 'Rails.application.routes'

  def project_path
    url_helpers.project_path(self)
  end
end

Let Webrat make a POST request

Just add the parameter :post to the visit method:

visit publish_entry_path, :post