Reputation: 103
When a user refreshes the page after submitting an invalid form, the browser should attempt to resubmit the form. In Chrome and Firefox (but not Safari) the browser performs a GET
request on the create/update url instead.
Removing Turbolinks fixes the problem - all browsers correctly call POST
on refreshing a submitted form page. It's not the first time that a Chrome update breaks Turbolinks, does anyone have a workaround?
Set up a new rails app and scaffold a test model called Thing
# using Ruby 2.3.1 and Rails 5.0.0
rails new testapp & cd testapp
rails generate scaffold Thing name:string
rails db:create db:migrate db:test:prepare
Make Thing.name
a required attribute
# app/models/thing.rb
class Thing < ActiveRecord::Base
validates :name, presence: true
end
Start a server and - in a browser - navigate to /things
name
, Rails will render the form again with the error Name can't be blank
.The browser should resubmit the form (usually asking "are you sure?" or similar), and render the same form-with-errors page.
Looking at the server output, we should see:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started POST "/things" # <= POST called, the form is resubmitted
In Chrome and Firefox (but not Safari), on page refresh the browser sends a GET
request to the POST
url, effectively calling index
.
Looking at the server output, I get:
# Navigate to /things
Started GET "/things"
# Click on "New Thing"
Started GET "/things/new"
# Click on "Create Thing" without filling in "name"
Started POST "/things" # <= attempts to create, fails, renders the form with errors
# Refresh the page
Started GET "/things" # <= expected POST
The issue is the same for edit
and update
. Assuming we have a valid Thing
with id: 1
saved in the database, this happens in Chrome and Safari:
# Click on "Edit Thing"
Started GET "/things/1/edit"
# Delete the existing "name" and click on "Update Thing"
Started PUT "/things/1" # <= attempts to update, fails, renders the form with errors
# Refresh the page
Started GET "/things/1" # <= expected POST
If the url is not RESTful, or if you just happen to have no index
or show
views, reloading causes the app to throw a "No route"
error.
Has anyone experienced this before? I can't find any traces of this in the Rails repo issues, but maybe I'm looking at it the wrong way.
I also tried with Ruby 2.1.2
and Rails 4.0.4
, and got the same results.
Upvotes: 3
Views: 943
Reputation: 94
i'm having the same problem! at last someone with the same problem.
I think it's because you might using turbolinks ver 5. or above. Downgrade your turbolinks to version before 5 (eg:ver 2.5.3) you should have the expected behaviour (browser resubmit the form and asking "are you sure?" or similar).
Using your 'how to replicate problem', i tried switching turbolink version couple times to make sure and confirm this result.
For now, if you do not want to remove turbolinks entirely, you can use earlier version.
Upvotes: 1