在轨道上form_for @article和form_for之间的差异:文章



我是Ruby on Rails的新手,当我尝试更新记录时,在以下用法之间感到困惑:

  1. <%= form_for @article, url:{action: "update"} do |form| %>这个有效,但我不明白为什么提交按钮显示"更新文章">

  2. <%= form_for :article, url:{action: "update"} do |form| %>这个抛出没有路由匹配 [POST] "/articles/2",提交按钮显示"保存文章">

最后:

  1. <%= 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_forform_tag的替代品

form_with将取代密切相关但签名非常不同的form_forform_tag方法。form_forform_tag已经软折旧,并计划拆除。

这个想法是提供具有更一致签名的单个方法。

如果您使用的是 Rails 5.1+,那么您应该使用这种方式。

看:

  • 轨道指南 - 操作视图表单帮助程序
  • Rails API - ActionView::Helpers::FormHelper
  • Rails 5.1 的form_with vs. form_tag vs. form_for

这一切都取决于@artical.如果@artical是新对象(@artical中的idnil),则调用创建操作。如果@artical是现有对象,则调用更新方法。

最新更新