ОБНОВЛЕНИЕ : Этот ответ относится к Rails 2, или если у вас есть специальные ограничения, требующие пользовательской логики. Простые случаи хорошо решаются с использованием fields_for, как обсуждалось в другом месте.
Rails не очень поможет вам в этом. Это идет вразрез со стандартными соглашениями о представлении, поэтому вам придется делать обходные пути в представлении, контроллере, даже маршрутах. Это не весело.
Ключевыми ресурсами для работы с многомодельными формами в Rails являются серия params-foo Стивена Чу , или, если вы на Rails 2.3, посмотрите Формы вложенных объектов
Становится намного проще, если вы определяете какой-то особый ресурс, который вы редактируете, например, Photoset. Photoset может быть реальной моделью ActiveRecord или просто фасадом, который принимает данные и выдает ошибки, как если бы это была модель ActiveRecord.
Теперь вы можете написать форму вида примерно так:
<%= form_for :photoset do |f|%>
<% f.object.photos.each do |photo| %>
<%= f.fields_for photo do |photo_form| %>
<%= photo_form.text_field :caption %>
<%= photo_form.label :caption %>
<%= photo_form.file_field :attached %>
<% end %>
<% end %>
<% end %>
Ваша модель должна проверять каждую входящую фотографию ребенка и объединять их ошибки. Вы можете проверить хорошую статью о том, как включить валидации в любой класс . Это может выглядеть примерно так:
class Photoset
include ActiveRecord::Validations
attr_accessor :photos
validate :all_photos_okay
def all_photos_okay
photos.each do |photo|
errors.add photo.errors unless photo.valid?
end
end
def save
photos.all?(&:save)
end
def photos=(incoming_data)
incoming_data.each do |incoming|
if incoming.respond_to? :attributes
@photos << incoming unless @photos.include? incoming
else
if incoming[:id]
target = @photos.select { |t| t.id == incoming[:id] }
end
if target
target.attributes = incoming
else
@photos << Photo.new incoming
end
end
end
end
def photos
# your photo-find logic here
@photos || Photo.find :all
end
end
Используя модель фасада для фотосета, вы можете сохранять свой контроллер и просматривать логику простым и понятным, резервируя самый сложный код для выделенной модели. Этот код, вероятно, не выйдет из коробки, но, надеюсь, он даст вам некоторые идеи и укажет правильное направление для решения вашего вопроса.