0

tl;dr : 新しいコミットを作成するための実際の関連情報が含まれていないようです。params[:commit]代わりに、名前も「commit」であるフォームの送信ボタンの値のみが含まれています。なぜこれが起こっているのかについてのアイデアはありますか? 私は何も変えませんでした。

関連するデバッグ情報が表示されるため、webrick サーバーで rails 3 を実行しています。属性が 1 つだけのモデルを作成しましたが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パーシャルで生成されたレールは次のとおりです。

<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、説明のテキスト領域が namecommit[description]であることが示されていますが、送信ボタンの名前commitです。したがって、どういうわけか、送信ボタンの値のみを取得しています。これは実際には「Create Commit」という値であり、必要な他の情報は取得していません。

私はレールについてあまり知らないので、これが事実なのか、それとも何なのかはよくわかりません。

誰か私を助けてください笑。

編集_form.html.erb:これは、レールによって生成された残りの部分です。おそらく、明白な問題を見つけることができます。

<%= 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」という名前が付けられるようになりました。これは、モデルの名前と競合します。私は同じくらい恐れていました。この名前を使用することにさらに意味があるかどうか疑問に思っています。この問題は、submit 呼び出しを次のように明示的に変更することで解決されました。

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

2 に答える 2

4

デフォルトでは、Rails scaffolding は次のようなフォームを作成します。

<%= 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' }

実際、それはレールが行ったことです。問題は、"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" />

もう 1 つのオプションは、'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は、のような名前のフィールドを生成しますcommit[description]。ただし、最後のsubitボタンの名前はcommit。です。最後の送信ボタンが前面を上書きすると思いますcommit[]

ぜひお試しください<%= f.submit "Your button text", :name => "something_else" %>

于 2010-11-04T01:14:32.400 に答える