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, поэтому = должен отображаться, но поля для даже не отображаются на странице или в сгенерированном 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

person ardavis    schedule 20.01.2012    source источник


Ответы (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 доступным атрибутом, поскольку ваша форма не будет его устанавливать.

person Ryan Bigg    schedule 23.01.2012
comment
Когда я проверяю перед изменением, я не вижу атрибутов course_attributes, а когда я делаю это f.fields_for, форма вообще не отображается. Так что-то должно быть не так с form_for проекта? - person ardavis; 23.01.2012
comment
Я обнаружил потенциальное решение, почему оно не появилось, проверьте ОБНОВЛЕНИЕ 2, но это лучший способ справиться с этим? - person ardavis; 23.01.2012
comment
Ах, поправьте, да, вам нужно сделать @course.build_project заранее. - person Ryan Bigg; 23.01.2012

Я использовал драгоценный камень dynamic_form. Таблица faculty_list (id, faculty_name) содержит названия факультетов.

<%= f.select :faculty, options_from_collection_for_select(@faculty_list, 'id', 'faculty_name', @faculty.faculty.to_i) %>
person Andrew Cazares    schedule 20.01.2012
comment
Я бы предпочел не использовать для этого лишний драгоценный камень, я хотел бы узнать, что говорят другие. Я тоже обновил свой вопрос. - person ardavis; 22.01.2012