Rails 3.2 Создание родительской модели из дочернего представления - PullRequest
2 голосов
/ 20 января 2012

Мне трудно понять, как это сделать. У меня есть две модели, проект и курс.

#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

Ответы [ 2 ]

3 голосов
/ 23 января 2012

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

0 голосов
/ 20 января 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) %>
...