【问题标题】:Rails 3 form actions and methodsRails 3 表单动作和方法
【发布时间】:2013-01-09 02:55:55
【问题描述】:

我做了一个资源。

resources :dashboards

我有一个包含表单的部分文件,我想使用这个部分文件(因为表单元素不会改变)来更新和创建。所以这就是我所拥有的:

控制器

class DashboardsController < ApplicationController
 def new     
    @dashboard = Dashboard.new
  end
end

查看

/dashboards/new.html.erb

<%= render :partial => "form", :locals => { :dashboard => @dashboard } %>

部分形式

/dashboards/_form.html.erb

<%= form_for(@dashboard) do |form| %>
.....
<% end %>

Ruby 指南

Ruby 指南指出:

应用程序的用户可以直接使用 Article 模型,因此 — 遵循使用 Rails 开发的最佳实践 — 您应该将其声明为资源。在处理 RESTful 资源时,如果您依赖记录标识,对 form_for 的调用会变得非常容易。 简而言之,您可以只传递模型实例,然后让 Rails 找出模型名称以及其余部分。 例如:

## Creating a new article
# long-style:
form_for(@article, :url => articles_path)
# same thing, short-style (record identification gets used):
form_for(@article)

## Editing an existing article
# long-style:
form_for(@article, :url => article_path(@article), :html => { :method => "put" })
# short-style:
form_for(@article)

结果

我认为我正确地遵循了 Rails 指南。因为我将@dashboard 设为资源。我可以将它传递到表单中并让它处理动作、方法和其余部分。相反,我得到了这个:

<form accept-charset="UTF-8" action="/dashboards" class="new_dashboard" id="new_dashboard_" method="post">

根据文档。我的表单的操作现在不应该是“/dashboards/new”,因为我们正在执行新操作吗?当我在 /edit 操作中使用相同的代码时,它是否应该传递一个额外的字段来声明要放置的方法??

无论如何,我的结果总是一样的。形式永远不会改变。

我做错了什么?

编辑

这是来自rake routes的我的路由器信息

GET    /dashboards(.:format)          dashboards#index
POST   /dashboards(.:format)          dashboards#create
GET    /dashboards/new(.:format)      dashboards#new
GET    /dashboards/:id/edit(.:format) dashboards#edit
GET    /dashboards/:id(.:format)      dashboards#show
PUT    /dashboards/:id(.:format)      dashboards#update
DELETE /dashboards/:id(.:format)      dashboards#destroy

【问题讨论】:

  • 好的,我得到了更改为当前控制器的表单操作。我在form_for 中传递@dashboard 而不是:dashboard。但是现在当我在控制器中执行 /new 操作时,表单操作不应该是 /dashboards/create 而不是 /dashboards/new?
  • 并且该方法也没有像指南所说的那样在表单中设置,如果我通过转到 /dashboard/:id/edit 进行更新
  • 如果您将其更改为:dashboard,那么您将切换到使用form tag helpers 而不是(面向资源的)form helpers。区别令人困惑,有关两者之间区别的更多信息,请参阅此答案:stackoverflow.com/questions/13537700/…
  • 您最初的内容大部分是正确的,但我会将@dashboard 切换为dashboardform_for(dashboard),因为您使用:locals =&gt; { :dashboard =&gt; @dashboard } 传入实例。
  • 啊@shioyama 你是对的。那解决了它。干杯!

标签: ruby-on-rails-3 forms


【解决方案1】:

您是正确的,您应该能够“将@dashboard 传递到表单中并让它处理动作、方法和其余部分。”这里的问题是 new 在 RESTful 操作的上下文中是什么。

当您使用resources :dashboards 声明一组资源时,您正在创建一组将请求映射到控制器操作的路由:

GET     /dashboards             index
GET     /dashboards/new         new
POST    /dashboards             create
GET     /dashboards/:id         show
GET     /dashboards/:id/edit    edit
PUT     /dashboards/:id         update
DELETE  /dashboards/:id         destroy

如果你运行rake routes,你可以检查这个。

这里的问题是new 操作被定义为对路径/dashboards/newGET 请求,即这是表单本身的路径。实际表单的 action 属性中的 URL 是另一回事:这是表单将通过 POST 请求将数据发布到的位置,在服务器(rails)端将映射到 create 控制器操作.

当您将表单助手与form_for(dashboard) 一起使用时,会创建一个表单,其路由对应于dashboard 是:如果它是一条新记录(即它尚不存在于数据库中),则该表单action 将是create(并指向/dashboards),而如果它已经存在,它将指向记录的实际URL(例如/dashboards/123)。这就是表单助手如此有用的原因。

所以,总而言之,/dashboards 是正确的 URL,不是针对 new 操作,而是针对 create 操作,表单助手使用它,因为 dashboard 是一个新记录。 new 是表单所在页面的路由,即/dashboards/new

希望这是有道理的。

附言作为旁注,如果您将其作为本地 (:locals =&gt; { :dashboard =&gt; @dashboard }) 传入,则不应在部分中访问 @dashboard。只需使用dashboard

【讨论】:

  • 嗨@shioyama 感谢您的快速回答。现在,当我查看localhost:3000/dashboards/new 时,表单操作是“/dashboards/new”,而不仅仅是“/dashboards”。将表单发布到 /dashboards/new 显然不起作用。我已将我的路线信息放在上面的帖子编辑中。
  • 你改变了什么吗?原来是/dashboards,没错。你应该有form_for(dashboard),而不是form_for(:dashboard)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多