Статья под названием Тройные вложенные формы в Rails представляет хорошее описание создания формы для сохранения трех вложенных объектов. В приведенном примере создается Show
, has_many Seasons
, и каждый Season
has_many Episodes
. Также Episode --> belongs_to --> Season --> belongs_to --> Show
. Шоу создаются следующим образом:
def new
@show = Show.new
@show.seasons.build.episodes.build
end
Форма выглядит следующим образом:
<%= form.fields_for :seasons do |s| %>
<%= s.label :number %>
<%= s.number_field :number %> <%= s.fields_for :episodes do |e| %>
<%= e.label :title %>
<%= e.text_field :title %>
<% end %>
<% end %>
<% end %>
Это кажется простым, поскольку все ассоциации выполняются в одном направлении. Я пытаюсь сделать что-то похожее, но более сложное. У меня есть модель Parent
, где каждый Parent
имеет несколько Children
, а каждый Child
зарегистрирован в School
. После указания, что Children
является множественным числом Child
, ассоциация должна быть такой:
Parent has_many Children, accepts_nested_attributes_for :children
Child belongs_to Parent, belongs_to School, accepts_nested_attributes_for :school
School has_many Children, accepts_nested_attributes_for :children
Графически это будет выглядеть так:
Parent <-- belongs_to <-- Child --> belongs_to --> School
КаждаяРодитель также связан с пользователем, например:
User has_many :parents
Данные о родителях, детях и школах вводятся в следующей форме (сгенерированной с использованием жемчужины простой формы), где школы вводятся каквыпадающий селектор из таблицы школ:
@schools = School.all
<%= simple_form_for (@parent) do |f| %>
<%= f.input :name, label: 'name' %>
<%= f.simple_fields_for :children, @children do |child_form| %>
<%= child_form.input :name, label: "Child Name" %>
<%= child_form.simple_fields_for :school, @school do |school %>
<%= school.collection_select :id, @schools, :id, :name, {}, {} %>
<% end %>
<% end %>
<% end %>
Я настроил метод контроллера new
, чтобы создать Parent
с тремя Children
, зарегистрированными в существующем School
. Затем я попытался связать Children
с School
, который уже существует в таблице schools
с id = 1.
def new
@parent = Parent.new
# creating 3 children
@children = Array.new(3) {@parent.children.build}
@school = School.find(1)
@school.children.build
end
Это выдает ошибку
Couldn't find School with ID=1 for Child with ID=
Ошибка находится в первой строке метода create, которая выглядит следующим образом:
def create
@parent = Parent.new(parent_params.merge(:user => current_user))
if @parent.save
redirect_to root_path
else
render :new, :status => :unprocessable_entity
end
end
def parent_params
params.require(:parent).permit(:name, :child_attributes => [:id, :name, age, :school_attributes => [:id, :name]])
end
Поскольку текст ошибки содержит состояние "Child with ID= "
, ошибка должна быть выдана, прежде чем будут назначены идентификаторы для новых Children
. ,Почему School
с ID = 1 нельзя найти, если он существует в таблице schools
? Или это означает, что запись School
не была правильно связана с экземпляром Child
до того, как была предпринята попытка сохранить этот экземпляр? Если так, как я могу исправить ассоциацию?