Rails 6.1: remote forms are no longer default?

After updating to Rails 6.1 I found that all my form_with helpers were broken. After some hunting I uncover config.action_view.form_with_generates_remote_forms: false is now the default setting.

Just so I understand (still a Rails beginner), I now have to add “local: false” to all my form_with helpers (or change the config default setting to true) in order to get ‘data-remote: true’ enabled on my forms? Seeking some clarification because the Rails 6.1 API docs seems at odds with this:

:local - By default form submits are remote and unobtrusive XHRs. Disable remote submits with local: true.

2 Likes

Yes, you are correct. Either add local: false or set the app config to true.

The documentation is a bit behind. The rewording was committed 14 days ago. Might be a few more days until a release happens and the docs get updated.

Annoying to get an unexpected backwards incompat, and really bad that the docs were not updated accordingly. But this is actually GREAT NEWS generally, default remote was terrible.

I am surprised it broke your app though. I think the intention is for all changes like this that unless you had changed to config.load_defaults 6.1 in your application.rb, or otherwise specifically written configuration to opt-in to the new behavior, you would still have gotten old behavior?

I think that’s the intention for all config changes like this; did it not happen with this one? I wonder if it’s a bug if it didn’t?

Thanks for the responses. Yes, I had updated config.load_defaults 6.1 as part of the upgrade, which I eventually isolated as the cause of the problem. (The forms using form_with were used by Stimulus controllers for which I hadn’t yet written tests, and since Stimulus itself was upgraded to 2.0 recently, I initially assumed it was the cause of the problem.)

To be clear, everything did work as expected when I used the 6.0 defaults. I just didn’t expect a breaking change when moving to 6.1 because the release notes didn’t mention anything about it - which seems odd, since the new default setting is the opposite of the previous one.

1 Like

FYI, the release notes don’t necessarily document every config change. That is what new_framework_defaults.rb is for; this file is generated when you run rails app:update (see docs here). This file allows you to gradually switch over to the new (6.1) defaults on by one, while still running config.load_defaults(6).

In this case the new framework defaults file included a toggle for the new setting: rails/new_framework_defaults_6_1.rb.tt at 6-1-stable · rails/rails · GitHub - though the comments there could probably be a bit better…

Oh, and in case you haven’t already figured it out - if you’re using Turbolinks, you’ll still want remote forms. But if you upgrade to Turbo Drive you’ll want remote: false. There’s some more discussion on this here: https://github.com/rails/rails/pull/40708

(can you tell I got stung by the same thing)

2 Likes

Understood, but it seems a significant enough change to warrant a bit more attention than being buried in a list of new config defaults. And though I did run app:update, it wasn’t completely clear to me what I was really agreeing to. Kind of like the programmer’s equivalent of Apple’s Terms of Service. :slight_smile:

Thanks for this. I first learned of Turbo when visiting the Stimulus forums while trying to solve this very problem. What I can’t seem to get confirmation of (though every indication points to it) is whether Turbolinks has been or will soon be deprecated. If so, then it seems best to leave the default config settings for 6.1 as they are, then install Turbo and have it take care of submitting forms via AJAX. Though I’m not looking forward to the inevitable ‘derailing’ this causes (which should be the preferred term for Rails upgrades gone bad), like how to get Turbo to work with Devise.

FWIW, I agree that this is significant enough that it really should have been mentioned in release notes. And documented more extensively in other places. But nothing is perfect. But I agree this was a mistake.

At least the new framework defaults are working as intended. In an ideal world, you would have had automated tests that would have failed with framework_defaults 6.1, to let you know that way… but nothing’s perfect.

Yeah, I think it could be made simpler, I actually have a PR up to make the task a bit easier to understand.

Thanks for the reminder, I was meant to share how I got this working - I had a simpler solution than that post. Adding it here.