Simon
Simon

Reputation: 103

Rails: unexpected behaviour in Chrome and Firefox when refreshing invalid form page

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.

EDIT

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?

Instructions to replicate the problem

  1. 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
    
  2. Make Thing.name a required attribute

    # app/models/thing.rb
    class Thing < ActiveRecord::Base
      validates :name, presence: true
    end
    
  3. Start a server and - in a browser - navigate to /things

  4. Attempt to create a new thing without providing a name, Rails will render the form again with the error Name can't be blank.
  5. Use the browser to refresh the page.

Expected behaviour

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

Actual behavior

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

It gets worse

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.

Help

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

Answers (1)

Aipack
Aipack

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

Related Questions