2

Using Ruby 2.5.1/Rails 5.2.4.1 I generated a new Rails app, and edited/created the following files:

# config/routes.rb
Rails.application.routes.draw do
  root 'some#home'
  post 'foo' => 'some#foo'
end
# app/controllers/some_controller.rb
class SomeController < ApplicationController
  def foo; end
end
# app/views/some/home.html.erb
<%= link_to 'Do stuff', foo_path, method: :post %>

If I click this link normally, it makes a POST request and gives a success response (204), as expected.

If I click to open it in a new tab (middle click/right click and 'Open link in new tab'), it makes a GET request and gives a 404/RoutingError.

This different behaviour depending on how I open (what appears by default to the user to be) a normal link seems surprising - is this the expected behaviour? I'm guessing this is something to do with this link using the Rails UJS and this behaving differently when a new tab is opened? What's the best way in Rails to get (what looks like) a link that makes a POST, no matter how it's opened?

Bob Whitelock
  • 167
  • 3
  • 12

1 Answers1

2

right-click and 'Open link in new tab' is just like copying the link and pasting in a new tab. Therefore it acts as a get-method.

Since you only accept post-method, RoutingError occurs.

btw, you can use target='_blank' if you want to open post-link in a new tab.

Fernand
  • 1,293
  • 1
  • 10
  • 18
  • 1
    Good point, I've not considered it that way before but that makes sense. I guess I should use `link_to` with a non-GET method carefully in future, as this seems like a bit of a gotcha with doing that. – Bob Whitelock Jan 14 '20 at 02:27
  • 3
    Reminder that `target='_blank'` might lead to [security vulnerabilities](https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/). – spickermann Jan 14 '20 at 07:18
  • 1
    he is still the owner of the page to be redirected (foo_path), so I guess it is not applicable here. But thank you for the heads up. – Fernand Jan 14 '20 at 08:53
  • Worth pointing out that while `target='_blank'` means the expected behaviour happens when the POST link is opened normally (it successfully opens in a new tab), the original issue still exists if a user tries to explicitly open it in a new tab. – Bob Whitelock Jan 14 '20 at 17:15