Rails 3.2 создание родительской модели из дочернего представления
Я имея трудное время понимание как это делать. У меня есть две модели, проект и курс.
#project.rb
belongs_to :course
attr_accessible :course_id, :course
accepts_nested_attributes_for :course, reject_if: lambda { |a| a[:course_id] == 0 }
#course.rb
has_many :projects
На странице Projects#new
(дочерний объект) я хочу ввести имя нового course
и заставить его создать родительский объект.
Вот моя попытка в представлении, но она, кажется, не работает правильно.
= form_for [@user, @project] do |f|
# Other fields
= fields_for :course do |builder|
= builder.label :name, 'Course Name'
= builder.text_field :name
= f.submit
Позже я буду использовать этот родительский объект для создания новых проектов, но пока предположим, что он не существует.
Обновление 1 Я модифицировал мои fields_for, чтобы быть (в соответствии с запросом Райана):
= form_for [@user, @project] do |f|
# Other fields
= f.fields_for :course do |builder|
= builder.label :name, 'Course Name'
= builder.text_field :name
= f.submit
Я использую haml, поэтому =
должен отображаться, но поля for даже не отображаются на странице или в сгенерированном html. Есть какие-нибудь догадки, почему это так? (Кнопка Отправить действительно отображается)
Обновление 2 Я нашел потенциальное решение, но не уверен, что это правильный подход. В контроллере мне нужно построить курс для отображения fields_for.
# ProjectsController
def new
@project = @user.projects.new
@project.build_course
end
# project.rb
attr_accessible :course_attributes
# So yes, I now see what you were talking about, regarding the course_attributes
2 ответа:
Вы должны использовать конструктор форм для построения Вашего объекта, а не просто
fields_for
сам по себе.У вас есть это:
= fields_for :course do |builder|
Где вы должны иметь это:
= f.fields_for :course do |builder|
Разница заключается в том, что, вызывая его на начальном построителе форм, Rails проверит, есть ли метод
course_attributes=
на объекте из начального вызоваform_for
(в этом случае это будет@project
), и если есть, то он определит поля внутри этой формы какcourse_attributes
.Вперед и проверьте форму до и после этого изменения, просто чтобы увидеть. Я подожду.
Это стало возможным благодаря вызову
accepts_nested_attributes_for
в вашей модели. Именно этот метод определяет методcourse_attributes=
, который позволяет вложенным атрибутам работать. После того, как вы создадите проект, он должен также создать курс.Кроме того, нет необходимости делать
course_id
доступным атрибутом, поскольку ваша форма не будет устанавливать его.