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