Sharing the Code

Programming stuff that might be useful to others

Rails form with a collection

Below is an example of a form for a ‘note’ that contains up to 3 photos.

edit.rhtml:
[sourcecode language=’ruby’]
<% form_for (:note, @note, :html=>{:multipart=>true}) do |note_field|
<%= note_field.text_field(:title) %>
<% @note.photos.each do |photo| %>
<% fields_for 'photo[]', photo) do |photo_field| <%= photo_field.file_field(:image, :accept=>‘image/jpeg,image/gif’) %>
<%= photo_field.text_field(:annotation) %>
<% end %>
<% end %>
<% for i in 0..2-@point.photos.length %>
<%= field_field('photo[new]', :image, :accept=>‘image/jpeg,image/gif’, :index=>i) %>
<%= text_field('photo[new]', :annotation, :index=>i) %>
<% end %>
<% end %>
[/sourcecode]

Lines 3-8 display the existing photos, in the generated HTML the fields will be expanded to something like photo[15][image], where 15 is the id of the photo. In lines 7-10 it iterates through new photo slots. The field names will be expanded to something like photo[new][0][image], where 0 is the index of the new photo.

notes_controller.rb:
[sourcecode language=’ruby’]
def edit
@note = Note.find(params[:id])
if request.post?
params[‘photo’].each do |key, value|
if key==’new’
params[‘photo’][‘new’].each_value do |value1|
if !value1.all?(&amp;:blank?)
photo = Photo.new(value1)
if photo.filename
@note.photos< ‘list’)
else
render(:action => ‘edit’)
end
end
end
[/sourcecode]

On line 4, it iterates through the hash params[‘photo’]. If the key is ‘new’ it then iterates through a nested hash of the new photos otherwise it updates existing photos. On line 7 it checks if the slot is blank and only adds it if it’s not.

Comments are closed