1) fields_for организует вложение атрибутов дочерних объектов в атрибуты родительских объектов в хэш params, который отправляется обратно в действие контроллера.Чтобы заставить Rails автоматически обновлять дочерние объекты, скажите родительской модели принять вложенные атрибуты, используя объявление accepts_nested_attributes_for .
2) Для каждого объекта ActiveRecord существует объект ошибок.Просмотрите список ошибок и отобразите сообщения.
Лучший способ добиться этого - создать вспомогательный метод и метод представления, который будет обрабатывать ошибки за вас.затем замените сгенерированные сообщения об ошибках в формах вызовом вашего метода render_error_messages.У вас есть весь код для этого уже в сгенерированных формах.Вам просто нужно реорганизовать этот код в частичное, создать помощника - который должен принимать массив имен моделей в качестве параметра, а затем делать то, что вы хотите с информацией.Отобразите частичное для каждой модели или создайте частичное, которое будет иметь дело с дочерними объектами, а также с родительским объектом.В общем, ваш вызов.
3) Измените новое действие, чтобы создать, а не создавайте новый дочерний объект, поэтому вместо
def new
@company = Company.new
@company.employees.new
end
сделайте это
def new
@company = Company.new
@company.employees.build
end
4)Посмотрите эти Railscasts, чтобы увидеть, как работает accepts_nested_attributes
http://railscasts.com/episodes/196-nested-model-form-part-1
и
http://railscasts.com/episodes/197-nested-model-form-part-2
Обновление
Так как вышеприведенная информация оставляет вас в связи с вашими вопросами.
1) Что у меня работает, но есть ли более чистый способ сделать это?
Вы исправили новое действие в соответствии с пунктом 3 выше, верно?Теперь ваше действие создания может выглядеть так:
def create
@company = Company.new(params[:company])
# save stuff
end
, что намного чище, поскольку оно вернулось к исходному сгенерированному действию создания.Вы можете не думать, что это большая часть обновления и, следовательно, не так уж и чище.Ну, в изоляции вы были бы правы.Но учтите, что вы можете добавить столько связей, сколько захотите, и добавить столько полей fields_for, сколько захотите, и вы можете превратить отношения user -> employee в has_many (я знаю, что вы этого не сделаете).Вы можете сделать все это, и ваши действия по созданию и обновлению останутся ТОЛЬКО ОДНЫМИ, и поэтому он чище.
2) , есть более чистый способ сделать это, чтобы я мог получить ошибки, специфичные для сотрудника? Учитывая мой ответ в пункте 2 выше, вы знаете, что есть объект ошибок как на объекте работника, так и на объекте пользователя, верно?Теперь вы также знаете, что можете обойти этот объект ошибок, чтобы получить правильные сообщения?Таким образом, вы могли бы сделать это
<% if @user.employee.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@user.employee.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.employee.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Рискнув себя, я просто скажу, что вам следует реорганизовать код представления сообщений об ошибках в парциальный, который примет любой объект в качестве параметра, после чего вы можете вызвать егос любого ракурса, что позволяет вам изменять стиль и функциональность для всех ваших форм.
Надеюсь, что понятнее