#ruby-on-rails #nested-forms
#ruby-on-rails #вложенные формы
Вопрос:
Я изучаю проект complex_form_example на github. Я изменил файл миграции так, чтобы:содержимое изменилось с t.text на t.string (как показано ниже): Пожалуйста, обратите внимание, что t.string — это единственное место, которое я изменил в примере проекта github, и до изменения все это работало.
class CreateQuestions < ActiveRecord::Migration
def self.up
create_table :questions do |t|
t.integer :survey_id
t.string :content
##t.text :content
t.timestamps
end
end
def self.down
drop_table :questions
end
end
Вот вложенная форма для кода:
<%= nested_form_for @survey do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :questions, :questions do |g|%>
<p>
<%= g.label :content, "Question" %><br />
<%= g.input :content, :rows => 3 %><br />
<%= g.link_to_remove "remove" %>
</p>
<%= g.fields_for :answers %>
<p><%= g.link_to_add "Add an answer", :answers %></p>
<% end %>
<p><%= f.link_to_add "Add a question", :questions %></p>
<p><%= f.submit "Submit" %></p>
<% end %>
И теперь я получаю следующее сообщение об ошибке:
undefined method `content' for :questions:Symbol
Extracted source (around line #10):
7: <%= f.fields_for :questions, :questions do |g|%>
8: <p>
9: <%= g.label :content, "Question" %><br />
10: <%= g.text_field :content, :rows => 3 %><br />
11: <%= g.link_to_remove "remove" %>
12: </p>
13: <%= g.fields_for :answers %>
Мой вопрос в том, существует ли fields_for для имени поля, которое напрямую поддерживает строковый тип?
Ответ №1:
У вас есть :questions, :questions
…Ты видишь это? :questions
появляется два раза раньше do
Комментарии:
1. Это действительно необходимо для rails 3.1.
2. Это также не отвечает на вопрос.
3. @JohnJiang Ты говоришь о
complex-form-examples
ryanb? Это Rails 3.0.4. И файл [app/views/surveys/_form.html.erb] github.com/ryanb/complex-form-examples/blob/master/app/views /…:questions
использовал один раз раньшеdo
. Если вы говорите о другом проекте examples в github, пожалуйста, предоставьте подробную информацию о ссылке. Должен ли я также подразумевать из вашего комментария, что вы используете Rails 3.1? Потому что в вашем вопросе неясно.4. @Panayotis: Да, вы правы, я использую rails 3.1. Проблема, похоже, решена. Должно быть, я не сопоставил fields_for с конечным тегом в представлении. Похоже, что, как вы предложили, достаточно тега one :questions .
5. @JohnJiang Хорошо. Поэтому, если вы считаете, что мое предложение было полезным, я был бы признателен, если не правильный ответ, проголосуйте за него. Кто-нибудь, проголосуйте против. Я не знаю почему.
Ответ №2:
fields_for
Помощник предназначен для получения объекта, для которого вы создаете поля, или, альтернативно, имени коллекции объектов, для которых нужно создавать поля.
Первый пример выглядит примерно так:
<%= f.fields_for :object do |object_fields| %>
# fields go here
В этом случае он создаст поля для этого объекта.
Второй пример тот же, но другой:
<%= f.fields_for :questions do |question_fields| 5>
# fields go here
<% end %>
Предполагая, что у вас есть questions
метод для любого объекта f
, который представляет, он будет перебирать все эти объекты в этой коллекции и представлять одни и те же поля для каждого из объектов.
Пожалуйста, обратите внимание: нет необходимости указывать :questions
второй раз. Вам нужно только один раз указать Rails.
Теперь, если вы делаете это, вы, вероятно, захотите иметь accepts_nested_attributes_for :questions
в родительской модели (что бы это ни было has_many :questions
), чтобы поля успешно передавались в контроллер и в create
update_attributes
вызовы модели or.
Комментарии:
1. спасибо вам за ваше очень подробное объяснение. Пожалуйста, смотрите мой ответ ниже о том, как я решил эту проблему. В настоящее время я поставлен в тупик тем фактом, что я не могу сохранять дочерние объекты во вложенной) форме. Это работает в проекте complex_form_example, но в моем собственном проекте я не использую restful обновление родительского объекта. Поэтому я не уверен, как я могу принудительно обновить родительский объект, чтобы также сохранить дочерние объекты. Ваша помощь будет высоко оценена!
Ответ №3:
Кажется, я решил свою собственную проблему, тщательно сопоставив fields_for tag с конечным тегом. Это работает следующим образом: в представлении / опросе
<%= nested_form_for @survey do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :questions do |g|%>
<%= render "question_fields", :f => g %>
<% end %>
<p><%= f.link_to_add "Add a question", :questions %></p>
<p><%= f.submit "Submit" %></p>
<% end %>
В частичных _question_fields:
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_field :content, :rows => 3 %><br />
<%= f.link_to_remove "remove" %>
</p>
<%= f.fields_for :answers %>
<p><%= f.link_to_add "Add an answer", :answers %></p>
Обратите внимание, что «f.fields_for :answers» по умолчанию использует частичные _answer_fields .