mirror of https://github.com/rails/rails
Change form_with to generate non remote forms by default
`form_with` would generate a remote form by default. This confused users because they were forced to handle remote requests. All new 6.1 applications will generate non-remote forms by default. When upgrading a 6.0 application you can enable remote forms by default by setting `config.action_view.form_with_generates_remote_forms` to `true`.
This commit is contained in:
parent
6f9d4a000b
commit
0a583c73c1
|
@ -1,4 +1,4 @@
|
|||
<%= form_with(model: message, local: true) do |form| %>
|
||||
<%= form_with(model: message) do |form| %>
|
||||
<% if message.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(message.errors.count, "error") %> prohibited this message from being saved:</h2>
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
* Change form_with to generate non-remote forms by default.
|
||||
|
||||
`form_with` would generate a remote form by default. This would confuse
|
||||
users because they were forced to handle remote requests.
|
||||
|
||||
All new 6.1 applications will generate non-remote forms by default.
|
||||
When upgrading a 6.0 application you can enable remote forms by default by
|
||||
setting `config.action_view.form_with_generates_remote_forms` to `true`.
|
||||
|
||||
*Petrik de Heus*
|
||||
|
||||
* `ActionView::Helpers::FormBuilder#id` returns the value
|
||||
of the `<form>` element's `id` attribute. With a `method` argument, returns
|
||||
the `id` attribute for a form field with that name.
|
||||
|
|
|
@ -823,7 +823,7 @@ The way this is done is to add a non-guessable token which is only known to your
|
|||
If you generate a form like this:
|
||||
|
||||
```erb
|
||||
<%= form_with model: @user, local: true do |form| %>
|
||||
<%= form_with model: @user do |form| %>
|
||||
<%= form.text_field :username %>
|
||||
<%= form.text_field :password %>
|
||||
<% end %>
|
||||
|
|
|
@ -700,7 +700,7 @@ Defaults to `'signed cookie'`.
|
|||
|
||||
* `config.action_view.debug_missing_translation` determines whether to wrap the missing translations key in a `<span>` tag or not. This defaults to `true`.
|
||||
|
||||
* `config.action_view.form_with_generates_remote_forms` determines whether `form_with` generates remote forms or not. This defaults to `true`.
|
||||
* `config.action_view.form_with_generates_remote_forms` determines whether `form_with` generates remote forms or not.
|
||||
|
||||
* `config.action_view.form_with_generates_ids` determines whether `form_with` generates ids on inputs.
|
||||
|
||||
|
@ -1024,6 +1024,7 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla
|
|||
- `config.action_dispatch.ssl_default_redirect_status` = `308`
|
||||
- `ActiveSupport.utc_to_local_returns_utc_offset_times`: `true`
|
||||
- `config.action_controller.urlsafe_csrf_tokens`: `true`
|
||||
- `config.action_view.form_with_generates_remote_forms`: `false`
|
||||
|
||||
#### For '6.0', defaults from previous versions below and:
|
||||
|
||||
|
|
|
@ -538,7 +538,7 @@ directory at `app/views/blorgh/comments` and in it a new file called
|
|||
|
||||
```html+erb
|
||||
<h3>New comment</h3>
|
||||
<%= form_with model: [@article, @article.comments.build], local: true do |form| %>
|
||||
<%= form_with model: [@article, @article.comments.build] do |form| %>
|
||||
<p>
|
||||
<%= form.label :text %><br>
|
||||
<%= form.text_area :text %>
|
||||
|
|
|
@ -33,7 +33,7 @@ The main form helper is [`form_with`](https://api.rubyonrails.org/classes/Action
|
|||
When called without arguments like this, it creates a form tag which, when submitted, will POST to the current page. For instance, assuming the current page is a home page, the generated HTML will look like this:
|
||||
|
||||
```html
|
||||
<form accept-charset="UTF-8" action="/" data-remote="true" method="post">
|
||||
<form accept-charset="UTF-8" action="/" method="post">
|
||||
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
|
||||
Form contents
|
||||
</form>
|
||||
|
@ -64,7 +64,7 @@ To create this form you will use `form_with` and the form builder object it yiel
|
|||
This will generate the following HTML:
|
||||
|
||||
```html
|
||||
<form action="/search" method="get" data-remote="true" accept-charset="UTF-8" >
|
||||
<form action="/search" method="get" accept-charset="UTF-8" >
|
||||
<label for="query">Search for:</label>
|
||||
<input id="query" name="query" type="text" />
|
||||
<input name="commit" type="submit" value="Search" data-disable-with="Search" />
|
||||
|
@ -217,7 +217,7 @@ The following form:
|
|||
Outputs:
|
||||
|
||||
```html
|
||||
<form action="/articles/42" method="post" data-remote="true" accept-charset="UTF-8" >
|
||||
<form action="/articles/42" method="post" accept-charset="UTF-8" >
|
||||
<input name="authenticity_token" type="hidden" value="..." />
|
||||
<input type="text" name="article[title]" id="article_title" value="My Title" />
|
||||
<textarea name="article[body]" id="article_body" cols="60" rows="10">
|
||||
|
@ -252,7 +252,7 @@ You can create a similar binding without actually creating `<form>` tags with th
|
|||
which produces the following output:
|
||||
|
||||
```html
|
||||
<form action="/people" accept-charset="UTF-8" data-remote="true" method="post">
|
||||
<form action="/people" accept-charset="UTF-8" method="post">
|
||||
<input type="hidden" name="authenticity_token" value="bL13x72pldyDD8bgtkjKQakJCpd4A8JdXGbfksxBDHdf1uC0kCMqe2tvVdUYfidJt0fj3ihC4NxiVHv8GVYxJA==" />
|
||||
<input type="text" name="person[name]" id="person_name" />
|
||||
<input type="text" name="contact_detail[phone_number]" id="contact_detail_phone_number" />
|
||||
|
@ -320,7 +320,7 @@ form_with(url: search_path, method: "patch")
|
|||
Output:
|
||||
|
||||
```html
|
||||
<form accept-charset="UTF-8" action="/search" data-remote="true" method="post">
|
||||
<form accept-charset="UTF-8" action="/search" method="post">
|
||||
<input name="_method" type="hidden" value="patch" />
|
||||
<input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
|
||||
...
|
||||
|
@ -329,7 +329,7 @@ Output:
|
|||
|
||||
When parsing POSTed data, Rails will take into account the special `_method` parameter and act as if the HTTP method was the one specified inside it ("PATCH" in this example).
|
||||
|
||||
IMPORTANT: All forms using `form_with` implement `remote: true` by default. These forms will submit data using an XHR (Ajax) request. To disable this include `local: true`. To dive deeper see [Working with JavaScript in Rails](working_with_javascript_in_rails.html#remote-elements) guide.
|
||||
IMPORTANT: In Rails 6.0 and 5.2, all forms using `form_with` implement `remote: true` by default. These forms will submit data using an XHR (Ajax) request. To disable this include `local: true`. To dive deeper see [Working with JavaScript in Rails](working_with_javascript_in_rails.html#remote-elements) guide.
|
||||
|
||||
Making Select Boxes with Ease
|
||||
-----------------------------
|
||||
|
@ -777,7 +777,7 @@ Let's say we want to render a form with a set of fields for each of a person's a
|
|||
Assuming the person had two addresses, with ids 23 and 45 this would create output similar to this:
|
||||
|
||||
```html
|
||||
<form accept-charset="UTF-8" action="/people/1" data-remote="true" method="post">
|
||||
<form accept-charset="UTF-8" action="/people/1" method="post">
|
||||
<input name="_method" type="hidden" value="patch" />
|
||||
<input id="person_name" name="person[name]" type="text" />
|
||||
<input id="person_address_23_city" name="person[address][23][city]" type="text" />
|
||||
|
|
|
@ -836,7 +836,7 @@ Let's create `app/views/articles/new.html.erb` with the following contents:
|
|||
```html+erb
|
||||
<h1>New Article</h1>
|
||||
|
||||
<%= form_with model: @article, local: true do |form| %>
|
||||
<%= form_with model: @article do |form| %>
|
||||
<div>
|
||||
<%= form.label :title %><br>
|
||||
<%= form.text_field :title %>
|
||||
|
@ -859,10 +859,6 @@ methods like [`label`](https://api.rubyonrails.org/classes/ActionView/Helpers/Fo
|
|||
and [`text_field`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-text_field)
|
||||
on the form builder to output the appropriate form elements.
|
||||
|
||||
NOTE: By default, `form_with` creates a form that submits via Ajax to avoid full
|
||||
page reloads. To make this guide easier to follow, we have disabled that feature
|
||||
by using `local: true` in the above code.
|
||||
|
||||
The resulting output from our `form_with` call will look like:
|
||||
|
||||
```html
|
||||
|
@ -980,7 +976,7 @@ display any error messages for `title` and `body`:
|
|||
```html+erb
|
||||
<h1>New Article</h1>
|
||||
|
||||
<%= form_with model: @article, local: true do |form| %>
|
||||
<%= form_with model: @article do |form| %>
|
||||
<div>
|
||||
<%= form.label :title %><br>
|
||||
<%= form.text_field :title %>
|
||||
|
@ -1144,7 +1140,7 @@ view called a *partial*. Let's create `app/views/articles/_form.html.erb` with
|
|||
the following contents:
|
||||
|
||||
```html+erb
|
||||
<%= form_with model: article, local: true do |form| %>
|
||||
<%= form_with model: article do |form| %>
|
||||
<div>
|
||||
<%= form.label :title %><br>
|
||||
<%= form.text_field :title %>
|
||||
|
@ -1494,7 +1490,7 @@ So first, we'll wire up the Article show template
|
|||
</ul>
|
||||
|
||||
<h2>Add a comment:</h2>
|
||||
<%= form_with model: [ @article, @article.comments.build ], local: true do |form| %>
|
||||
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
|
||||
<p>
|
||||
<%= form.label :commenter %><br>
|
||||
<%= form.text_field :commenter %>
|
||||
|
@ -1573,7 +1569,7 @@ add that to the `app/views/articles/show.html.erb`.
|
|||
<% end %>
|
||||
|
||||
<h2>Add a comment:</h2>
|
||||
<%= form_with model: [ @article, @article.comments.build ], local: true do |form| %>
|
||||
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
|
||||
<p>
|
||||
<%= form.label :commenter %><br>
|
||||
<%= form.text_field :commenter %>
|
||||
|
@ -1637,7 +1633,7 @@ following:
|
|||
<%= render @article.comments %>
|
||||
|
||||
<h2>Add a comment:</h2>
|
||||
<%= form_with model: [ @article, @article.comments.build ], local: true do |form| %>
|
||||
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
|
||||
<p>
|
||||
<%= form.label :commenter %><br>
|
||||
<%= form.text_field :commenter %>
|
||||
|
@ -1664,7 +1660,7 @@ Let us also move that new comment section out to its own partial. Again, you
|
|||
create a file `app/views/comments/_form.html.erb` containing:
|
||||
|
||||
```html+erb
|
||||
<%= form_with model: [ @article, @article.comments.build ], local: true do |form| %>
|
||||
<%= form_with model: [ @article, @article.comments.build ] do |form| %>
|
||||
<p>
|
||||
<%= form.label :commenter %><br>
|
||||
<%= form.text_field :commenter %>
|
||||
|
|
|
@ -168,12 +168,11 @@ remote elements inside your application.
|
|||
#### form_with
|
||||
|
||||
[`form_with`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_with)
|
||||
is a helper that assists with writing forms. By default, `form_with` assumes that
|
||||
your form will be using Ajax. You can opt out of this behavior by
|
||||
passing the `:local` option to `form_with`.
|
||||
is a helper that assists with writing forms. To use Ajax for your form you can
|
||||
pass the `:local` option to `form_with`.
|
||||
|
||||
```erb
|
||||
<%= form_with(model: @article, id: "new-article") do |form| %>
|
||||
<%= form_with(model: @article, id: "new-article", local: false) do |form| %>
|
||||
...
|
||||
<% end %>
|
||||
```
|
||||
|
|
|
@ -181,6 +181,10 @@ module Rails
|
|||
action_controller.urlsafe_csrf_tokens = true
|
||||
end
|
||||
|
||||
if respond_to?(:action_view)
|
||||
action_view.form_with_generates_remote_forms = false
|
||||
end
|
||||
|
||||
ActiveSupport.utc_to_local_returns_utc_offset_times = true
|
||||
else
|
||||
raise "Unknown version #{target_version.to_s.inspect}"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<%%= form_with(model: <%= model_resource_name %>, local: true) do |form| %>
|
||||
<%%= form_with(model: <%= model_resource_name %>) do |form| %>
|
||||
<%% if <%= singular_table_name %>.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
|
||||
|
|
|
@ -43,3 +43,6 @@
|
|||
# effect. For applications using multiple databases, this new API provides
|
||||
# support for granular connection swapping.
|
||||
# Rails.application.config.active_record.legacy_connection_handling = false
|
||||
|
||||
# Make `form_with` generate non-remote forms by default.
|
||||
# Rails.application.config.action_view.form_with_generates_remote_forms = false
|
||||
|
|
|
@ -906,7 +906,7 @@ module ApplicationTests
|
|||
|
||||
test "form_with can be configured with form_with_generates_remote_forms" do
|
||||
app_file "config/initializers/form_builder.rb", <<-RUBY
|
||||
Rails.configuration.action_view.form_with_generates_remote_forms = false
|
||||
Rails.configuration.action_view.form_with_generates_remote_forms = true
|
||||
RUBY
|
||||
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
|
@ -932,38 +932,38 @@ module ApplicationTests
|
|||
|
||||
app "development"
|
||||
|
||||
get "/posts"
|
||||
assert_no_match(/data-remote/, last_response.body)
|
||||
end
|
||||
|
||||
test "form_with generates remote forms by default" do
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
class Post
|
||||
include ActiveModel::Model
|
||||
attr_accessor :name
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "app/controllers/posts_controller.rb", <<-RUBY
|
||||
class PostsController < ApplicationController
|
||||
def index
|
||||
render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
add_to_config <<-RUBY
|
||||
routes.prepend do
|
||||
resources :posts
|
||||
end
|
||||
RUBY
|
||||
|
||||
app "development"
|
||||
|
||||
get "/posts"
|
||||
assert_match(/data-remote/, last_response.body)
|
||||
end
|
||||
|
||||
test "form_with generates non remote forms by default" do
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
class Post
|
||||
include ActiveModel::Model
|
||||
attr_accessor :name
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file "app/controllers/posts_controller.rb", <<-RUBY
|
||||
class PostsController < ApplicationController
|
||||
def index
|
||||
render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
|
||||
add_to_config <<-RUBY
|
||||
routes.prepend do
|
||||
resources :posts
|
||||
end
|
||||
RUBY
|
||||
|
||||
app "development"
|
||||
|
||||
get "/posts"
|
||||
assert_no_match(/data-remote/, last_response.body)
|
||||
end
|
||||
|
||||
test "default method for update can be changed" do
|
||||
app_file "app/models/post.rb", <<-RUBY
|
||||
class Post
|
||||
|
|
Loading…
Reference in New Issue