2010-11-04 4 views
0

tl; dr: Кажется, что params[:commit] не содержит актуальную информацию для создания нового Commit, вместо этого он содержит только значение кнопки отправки для формы, имя которой также «совершает». Любые идеи относительно того, почему это происходит? Я ничего не изменил.Невозможно создать новую модель в Rails

Я запускаю рельсы 3 с сервером Webrick, так как он отображает соответствующую информацию для отладки. Я создал модель с одним атрибутом, 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 отлично работает, когда я создаю его и сохраняю его вручную, поэтому у меня возникает ощущение, что в контроллере происходит разъединение, когда оно идет на сохранение или что-то в этом роде.

EDIT: Я заметил что-то интересное. В контроллере, объект создается как, например:

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

Однако, как отмечено в выходных данных WEBrick выше, параметры сервера получает только:

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

Так что не похоже он получает параметр description, который, как я полагаю, должен был быть обернут в параметр commit, но если я посмотрю на источник формы new, это показывает, что текстовая область описания имеет имя commit[description], но кнопка отправки имеет имя commit. Так почему-то он получает только значение кнопки «Отправить», которая действительно имеет значение «Создать коммит», а не другую требуемую им информацию.

Я не знаю, что много о рельсах, хотя я не знаю, действительно ли это так или нет.

Кто-то, пожалуйста, помогите мне ха-ха.

EDIT: Остальная часть _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 теперь автоматически дает каждую кнопку отправки название «совершить», который конфликтует с именем моей модели. Я боялся столько же. Мне интересно, есть ли какие-либо дальнейшие последствия для использования этого имени. Эта проблема была решена путем явного изменения вызова представить:

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

Вы можете включать в себя остальную часть вашей формы, пожалуйста. – mark

+0

@mark: конечно, я просто не думал, что это будет актуально, так как это именно то, что рельсы генерируют всегда свалками. Я поставлю его прямо сейчас, хотя :) –

+0

Выглядит нормально. Единственное, что я могу догадаться, это фиксация - вероятный кандидат на зарезервированное слово, возможно, новое в rails 3? – mark

ответ

4

По умолчанию рельсов леса будет создать форму, которая будет выглядеть примерно так:

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

Гоча вы столкнулись это имя столкновения между именем кнопки отправки и имени объекта. Обычно, когда рельсы встречает имя формы, как «совершить [Описание]» он будет хранить результаты в @params так что значение выглядит следующим образом:

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

На самом деле, это то, что рельсы сделал. Проблема заключалась в том, что имя по умолчанию, сгенерированное помощником формы «submit_tag», также называется «commit». Поэтому, когда рельсы столкнулись, что параметр формы он переписал результаты формы, как это:

@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

+0

Спасибо, Берин, это очень информативный ответ. Я просто хочу спросить тебя об одном. Я понимаю ваши решения, они имеют смысл, но могу ли я просто сделать то, что рекомендовал PeterWong, изменить имя тега submit? В конце концов, я понимаю, что это столкновение произойдет только в форме создания модели Commit, правильно? Независимо от того, что я буду принимать ваш ответ, поскольку он более информативен, но я был бы признателен за ответ. –

+0

Это правильно. Основным виновником является столкновение имен, поэтому ваш выбор заключается в изменении имени отправки или имени, используемого для вашего объекта. –

+0

Спасибо, я ценю это. –

1

form_for генерирует поля с именем, как commit[description]. Однако последняя кнопка субтитров имеет имя commit. Я думаю, что последняя кнопка отправки перезаписывает передние commit[] s.

Поэтому, пожалуйста, попробуйте <%= f.submit "Your button text", :name => "something_else" %>

+0

Спасибо. После дальнейшего расследования кажется, что Rails 3 автоматически дает каждой кнопке отправки имя «commit», что противоречит имени моей модели. Это исправляет это. Тем не менее, я обеспокоен тем, смогу ли я столкнуться с чем-то подобным позже, если я сохраню это имя для модели. –

+0

Ya, даже для 'submit_tag', он автоматически добавляет имя' commit'. Таким образом, вы бы лучше переименовали свою модель или перезаписали имя кнопки или с помощью настраиваемого конструктора форм, который автоматически перезаписывает имя кнопки отправки. – PeterWong

Смежные вопросы