0

tl;dr:似乎params[:commit]不包含创建新提交的实际相关信息,相反,它只包含名称也是“提交”的表单的提交按钮的值。关于为什么会发生这种情况的任何想法?我没有改变任何东西。

我正在使用 webrick 服务器运行 rails 3,因为它显示了相关的调试信息。我创建了一个只有一个属性的模型,description:text,一切似乎都运行良好。

但是,当我使用自动生成的脚手架表单创建一个新的脚手架时,它似乎并不关心描述文本区域的值。换句话说,在创建之后,该created_at列很好,除了 之外,其他所有内容description都没有显示。这是服务器的输出:

Started POST "/commits" for 127.0.0.1 at 2010-11-03 17:24:20 -0700
Processing by CommitsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"F00A8Ttv7ceREegfZmP+T5kr+6u2YbRJrQzmfEOaT7o=", "commit"=>"Create Commit"}
SQL (0.5ms)  INSERT INTO "commits" ("created_at", "description", "updated_at") VALUES ('2010-11-04 00:24:20.986571', NULL, '2010-11-04 00:24:20.986571')
Redirected to http://0.0.0.0:3000/commits/5
Completed 302 Found in 42ms

这是我的迁移的样子,由自动生成rails generate

def self.up
  create_table :commits do |t|
    t.text :description

    t.timestamps
  end
end

如您所见,NULL即使我确实在文本区域中输入了某些内容,它也会看到描述值。这是_form.html.erb部分生成的rails:

<div class="field">
  <%= f.label :description %><br />
  <%= f.text_area :description %>
</div>

任何人对为什么会发生这种情况有任何想法?我很确定这也是显而易见的事情。

顺便说一句,rails console当我创建一个并手动保存它时工作正常,所以我感觉控制器在保存时会断开连接。

编辑:我注意到一些有趣的事情。在控制器中,对象是这样创建的:

@commit = Commit.new(params[:commit])

但是,正如上面 webrick 输出中所指出的,服务器接收的参数只有:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"F00A8Ttv7ceREegfZmP+T5kr+6u2YbRJrQzmfEOaT7o=", "commit"=>"Create Commit"}

所以它似乎没有得到description参数,我想它应该被包装在commit参数中,但是如果我查看new表单的源代码,它显示描述的文本区域是 name commit[description],但是提交按钮是名字commit。所以不知何故,它只获得了提交按钮的值,它确实具有“创建提交”的价值,而不是它需要的其他信息。

我对rails了解不多,所以我真的不知道是这种情况还是什么。

有人请帮帮我哈哈。

编辑_form.html.erb:这是由 rails 生成的其余部分。也许你可以发现一个明显的问题:

<%= form_for(@commit) do |f| %>
  <% if @commit.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@commit.errors.count, "error") %> prohibited this commit from being saved:</h2>

      <ul>
      <% @commit.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :description %><br />
    <%= f.text_area :description %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

:Rails 3 现在似乎自动为每个提交按钮命名为“commit”,这与我的模型名称冲突。我同样害怕。我想知道使用此名称是否有任何进一步的含义。通过将提交调用显式更改为:

f.submit "Button Text", :name => "something_else"
4

2 回答 2

4

默认情况下,rails 脚手架将创建一个如下所示的表单:

<%= form_for @commit do |f| %>
  <%= f.label :description %>
  <%= f.text_area :description %>
  <%= submit_tag "Create" %>
<% end %>

请注意,我已将部分内容折叠到表单本身中。重要的是要了解发生这种情况时会生成什么 HTML。它看起来像这样:

<form action="/commits/create" method="post">
  <label for="commit_description">Description:</label>
  <textarea id="commit_description" name="commit[description]"></textarea>
  <input name="commit" type="submit" value="Create" />
</form>

您遇到的问题是提交按钮名称和对象名称之间的名称冲突。通常,当 rails 遇到像 "commit[description]" 这样的表单名称时,它会将结果存储在 @params 中,因此值如下所示:

@params[:commit] = { :description => 'value' }

事实上,这就是rails所做的。问题是“submit_tag”表单助手生成的默认名称也被命名为“commit”。因此,当 rails 遇到该表单参数时,它会覆盖表单的结果,如下所示:

@params[:commit] = "Create" # same name as the value of the submit button

要解决此名称冲突,您有几个选择。第一种选择是用普通的旧 HTML 手写提交按钮。当然你失去了一些选项,但至少你可以将提交按钮的名称更改为其他名称:

<input type="submit" name="who_cares" value="Create Commit" />

另一种选择是使用“form_for”助手的变体。在这种情况下,表单的开头行如下所示:

<%= form_for :newcommit, @commit, :url => { :action => "create" } do |f| %>
  <%= f.label :description %>
  <%= f.text_area :description %>
  <%= submit_tag "Create" %>
<% end %>

这会将生成的 HTML 更改为如下所示:

<form action="/commits/create" method="post">
  <label for="newcommit_description">Description:</label>
  <textarea id="newcommit_description" name="newcommit[description]"></textarea>
  <input name="commit" type="submit" value="Create" />
</form>

这会将您的表单数据绑定到 @params[:newcommit] 参数,并且您可以正常继续处理。

为了您的进一步阅读乐趣:

http://guides.rubyonrails.org/form_helpers.html

于 2010-11-04T01:29:57.463 回答
1

form_for 生成名称为 like 的字段commit[description]。但是,最后一个 subit 按钮的名称为commit. 我认为最后一个提交按钮会覆盖 fore commit[]

所以请尝试<%= f.submit "Your button text", :name => "something_else" %>

于 2010-11-04T01:14:32.400 回答