Rails route to catch non-GET requests to root path

We needed to add a specific line into our routes.rb file to cover non-GET requests going to the root path.

For the longest time I’ve been adding a catch-all to the bottom of my routes.rb file to say “Can’t find an appropriate route? Have a 404”. A recent project highlighted a need to add a second line in order to properly catch non-GET requests to the root path.

Up until now I’ve been adding a line like this to the bottom of my routes.rb file;

match '*url' => 'errors#not_found', via: :all

This says “match any other URL via any HTTP verb and send it to the not_found action in the ErrorsController”.

Sorry, almost any other URL. I mistakenly thought that the * part would match the root URL too, so visiting /. It turns out it doesn’t.

I was seeing a lot of errors being logged that looked like rails No route matches [POST] "/" or rails No route matches [OPTIONS] "/".

In both cases, requests like POST /broken-url or OPTIONS /lol would be correctly picked up and handled by our catch-all.

The fix is to have another line just above our catch-all,focusing on just the root. So;

match '/' => 'errors#not_found', via: [:post, :put, :patch, :delete, :options]

The reason we don’t do a via: :all here is because in most Rails projects we want the root path to go somewhere via a GET request. Most routes.rb files will have a line that looks like;

root 'static#home'

If we got all the way to the bottom and that wasn’t accessed, throw an error we can track in our error logs.

Our final two lines now look like this;

match '/' => 'errors#not_found', via: [:post, :put, :patch, :delete, :options]
match '*url' => 'errors#not_found', via: :all

Recent posts View all

Web Dev

Creating draft posts in Jekyll

How to create and develop with draft posts in Jekyll

Ruby

Forcing a Rails database column to be not null

How you can force a table column to always have something in it with Rails