I have a structure that looks like this... a teacher (name, address, etc) each teacher has multiple instruments they teach, from an array of all the instruments So, I want to display a page with all the teacher records, and the instruments as checkboxes. I can display the collection of teacher names in fields for editing, for example, like this: <%= text_field("teacher[]", "lastname", :size=>15) %> #note the [] after teacher But how would I display all the checkboxes associated with each teacher so that they can be picked up in the controller? I tried something like this: <% @instruments.each do |i| %> <input type="checkbox" id="<%= i %>" name="teacher[][instruments][]" value="<%= i %>"<% if (@teacher.has_instrument?(r.id)) %> checked="checked" <% end %>> <%= t.name %> <% end %> First of all, it doesn''t work - the controller does not see that these checkboxes are associated with that particular teacher. Also, it seems ugly... Can anyone give me some guidance here? Thanks Shelby
> But how would I display all the checkboxes associated with each > teacher so that they can be picked up in the controller? > > I tried something like this: > <% <at> instruments.each do |i| %> > <input type="checkbox" id="<%= i %>" name="teacher[][instruments][]" > value="<%= i %>"<% if ( <at> teacher.has_instrument?(r.id)) %> > checked="checked" <% end %>> > <%= t.name %> > <% end %>A solution with some manual work on your part is to have the checkbox named: teacher[1][is_checked] and a companion hidden field like: <input type="hidden" name=teacher[1][id]" value="10" /> which will have the instrument id. It''s a little hard to explain but if you do this and examine the params hash, you''ll see what I''m talking about. Then some additional work to determine which instruments to insert/update/delete.
The warning sign I see here is that you''re not using the :index => property of the input tag. I''d look at using the render(:partial =>) helper to loop over your ''instruments'' variable. I''m doing something like this for text fields and select boxes, though I''ve never tried it for checkboxes. <td id="sex<%= member_counter %>"><%= select ''member'', ''sex_code'', [[''Unknown'',''U''], [''Male'',''M''], [''Female'',''F'']], {}, {''index'' => member_counter, ''class'' => ''required''} %></td> That lets me use the form helpers, despite there being an arbitrary number of ''members''. "member_counter" is defined because of the way the partial was called: <%= render(:partial => ''member'', :collection => @members) %> --Wilson. Steve Downey wrote:>>But how would I display all the checkboxes associated with each >>teacher so that they can be picked up in the controller? >> >>I tried something like this: >> <% <at> instruments.each do |i| %> >> <input type="checkbox" id="<%= i %>" name="teacher[][instruments][]" >>value="<%= i %>"<% if ( <at> teacher.has_instrument?(r.id)) %> >>checked="checked" <% end %>> >> <%= t.name %> >> <% end %> > > > A solution with some manual work on your part is to have the checkbox named: > > teacher[1][is_checked] > > and a companion hidden field like: > > <input type="hidden" name=teacher[1][id]" value="10" /> > > which will have the instrument id. It''s a little hard to explain but if you do > this and examine the params hash, you''ll see what I''m talking about. Then some > additional work to determine which instruments to insert/update/delete.
I thought this wouldn''t work because render(:partial => ''member'', :collection => @members) %> would define a *local* variable "member" inside the partial, when what you need is an instance variable @member to feed to the form helper. This has always bothered me, I''m not sure if I just don''t understand how it should work or what, but this is what I''ve been doing in cases like this: <% @objects.each_with_index do |@object, index| %> <%= render :partial => ''object_partial'' %> <% end %> And in the partial, it just uses <% text_field ''object'', ''attribute'', ''index'' => index %> Please educate me if I am misunderstanding something, this is the best solution I''ve come up with. -Jeff ----- Original Message ----- From: "Wilson" <defiler-ifvz4xmYPRU@public.gmane.org> To: <rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org> Sent: Thursday, July 28, 2005 2:31 PM Subject: Re: [Rails] Re: collection of collections checkboxes> The warning sign I see here is that you''re not using the :index => > property of the input tag. > I''d look at using the render(:partial =>) helper to loop over your > ''instruments'' variable. > I''m doing something like this for text fields and select boxes, though > I''ve never tried it for checkboxes. > <td id="sex<%= member_counter %>"><%= select ''member'', ''sex_code'', > [[''Unknown'',''U''], [''Male'',''M''], [''Female'',''F'']], {}, {''index'' => > member_counter, ''class'' => ''required''} %></td> > > That lets me use the form helpers, despite there being an arbitrary number > of ''members''. "member_counter" is defined because of the way the partial > was called: > <%= render(:partial => ''member'', :collection => @members) %> > > --Wilson. > > Steve Downey wrote: >>>But how would I display all the checkboxes associated with each >>>teacher so that they can be picked up in the controller? >>> >>>I tried something like this: >>> <% <at> instruments.each do |i| %> >>> <input type="checkbox" id="<%= i %>" name="teacher[][instruments][]" >>>value="<%= i %>"<% if ( <at> teacher.has_instrument?(r.id)) %> >>>checked="checked" <% end %>> >>> <%= t.name %> >>> <% end %> >> >> >> A solution with some manual work on your part is to have the checkbox >> named: >> >> teacher[1][is_checked] >> >> and a companion hidden field like: >> >> <input type="hidden" name=teacher[1][id]" value="10" /> which will have >> the instrument id. It''s a little hard to explain but if you do >> this and examine the params hash, you''ll see what I''m talking about. >> Then some >> additional work to determine which instruments to insert/update/delete. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails
In regards to the checkboxes, I ended up doing what Steve Downey suggested - artificially inserting the id into the checkbox name field. It is clumsy, but it works. Looks like this: <% for teacher in @teachers do %> teacher, first name stuff teacher lastname stuff <% INSTRUMENTS.each do |i| %> <%= i %>:<input type=''checkbox'' id=''<%= i %>'' name=<%= "teacher[" + @teacher.id.to_s + "][instruments][]"%> value=''<%= i %>'' <% if @teacher.has_instrument?(i) %> checked="checked"<% end %> /> <% end %> <% end %> I wish there were a helper for this. Certainly it needs to be done rather often... Shelby
DHH showed me this trick, so now it''s my duty to share it. Heh. Just do: <%= render :partial => ''whatever'', :collection => @whatevers %> ..and in the partial form itself, put: <% @whatever = whatever -%> at the top. Silly, but it works. Now you have an instance variable that you can use with the usual form helpers. You can (carefully) build the checkboxes up ''by hand'', but there''s no need. Jeffrey Moss wrote:> I thought this wouldn''t work because render(:partial => ''member'', > :collection => @members) %> would define a *local* variable "member" > inside the partial, when what you need is an instance variable @member > to feed to the form helper. This has always bothered me, I''m not sure if > I just don''t understand how it should work or what, but this is what > I''ve been doing in cases like this: > > <% @objects.each_with_index do |@object, index| %> > <%= render :partial => ''object_partial'' %> > <% end %> > > And in the partial, it just uses <% text_field ''object'', ''attribute'', > ''index'' => index %> > > Please educate me if I am misunderstanding something, this is the best > solution I''ve come up with. > > -Jeff > > ----- Original Message ----- From: "Wilson" <defiler-ifvz4xmYPRU@public.gmane.org> > To: <rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org> > Sent: Thursday, July 28, 2005 2:31 PM > Subject: Re: [Rails] Re: collection of collections checkboxes > > >> The warning sign I see here is that you''re not using the :index => >> property of the input tag. >> I''d look at using the render(:partial =>) helper to loop over your >> ''instruments'' variable. >> I''m doing something like this for text fields and select boxes, though >> I''ve never tried it for checkboxes. >> <td id="sex<%= member_counter %>"><%= select ''member'', ''sex_code'', >> [[''Unknown'',''U''], [''Male'',''M''], [''Female'',''F'']], {}, {''index'' => >> member_counter, ''class'' => ''required''} %></td> >> >> That lets me use the form helpers, despite there being an arbitrary >> number of ''members''. "member_counter" is defined because of the way >> the partial was called: >> <%= render(:partial => ''member'', :collection => @members) %> >> >> --Wilson. >> >> Steve Downey wrote: >> >>>> But how would I display all the checkboxes associated with each >>>> teacher so that they can be picked up in the controller? >>>> >>>> I tried something like this: >>>> <% <at> instruments.each do |i| %> >>>> <input type="checkbox" id="<%= i %>" name="teacher[][instruments][]" >>>> value="<%= i %>"<% if ( <at> teacher.has_instrument?(r.id)) %> >>>> checked="checked" <% end %>> >>>> <%= t.name %> >>>> <% end %> >>> >>> >>> >>> A solution with some manual work on your part is to have the checkbox >>> named: >>> >>> teacher[1][is_checked] >>> >>> and a companion hidden field like: >>> >>> <input type="hidden" name=teacher[1][id]" value="10" /> which will >>> have the instrument id. It''s a little hard to explain but if you do >>> this and examine the params hash, you''ll see what I''m talking about. >>> Then some >>> additional work to determine which instruments to insert/update/delete. >>