我是Ruby on Rails的新手,当我尝试更新记录时,在以下用法之间感到困惑:
-
<%= form_for @article, url:{action: "update"} do |form| %>
这个有效,但我不明白为什么提交按钮显示"更新文章"> -
<%= form_for :article, url:{action: "update"} do |form| %>
这个抛出没有路由匹配 [POST] "/articles/2",提交按钮显示"保存文章">
最后:
<%= form_with(model: @article) do |form| %>
实际上更新了记录,但我不明白为什么它调用更新,而不是其他方法
form_for(@article)
创建一个绑定到模型实例的表单生成器。
如果@article
为零,则会引发错误。
如果实例是新记录,则表单将使用method="POST"
和action="/arcticles"
。
如果记录已持久保存,它将具有method="PATCH"
和action="/arcticles/:article_id"
。
Rails 根据约定而不是配置派生操作属性的 URL。因此,如果您遵循约定,则无需显式传递 url 选项。
这方面的一个例子是:
<% @article = Article.new(title: 'Hello World') %>
<%= form_for(@article) do |f| %>
<%= f.text_input :title %>
<% end %>
这将呈现如下内容:
<form action="/articles" method="POST">
<input type="text" name="article[title]" value="Hello World"/>
...
</form>
<%= form_for @article, url:{action: "update"} do |form| %>
这个 有效,但我不明白为什么提交按钮显示"更新" 文章'
表单构建器通过对您传递给form_with
的记录调用.new_record?
来知道它正在更新记录。您可以通过提供翻译来更改提交按钮的默认值:
# config/locales/en.yml
en:
helpers:
submit:
create: "Save new record"
update: "Save changes"
form_for(:article)
创建一个不包装对象的作用域表单生成器。
这将创建一个表单构建器,其中输入将被"限定范围"。例如:
<%= form_for(:article) do |f| %>
<%= f.text_input :title %>
<% end %>
这将呈现如下内容:
<form action="/articles" method="POST">
<input type="text" name="article[title]"/>
...
</form>
Rails 根据约定而不是配置派生操作属性的 URL。
在您的情况下,<%= form_for :article, url:{action: "update"} do |form| %>
会导致路由错误,因为form_for
默认为method: "POST"
。
form_with
是 Rails 5.1 对form_for
和form_tag
的替代品
form_with
将取代密切相关但签名非常不同的form_for
和form_tag
方法。form_for
和form_tag
已经软折旧,并计划拆除。
这个想法是提供具有更一致签名的单个方法。
如果您使用的是 Rails 5.1+,那么您应该使用这种方式。
看:
- 轨道指南 - 操作视图表单帮助程序
- Rails API - ActionView::Helpers::FormHelper
- Rails 5.1 的form_with vs. form_tag vs. form_for
这一切都取决于@artical
.如果@artical
是新对象(@artical
中的id
是nil
),则调用创建操作。如果@artical
是现有对象,则调用更新方法。