Hi All, Pardon me if this is in a FAQ somewhere, feel free to tell me to RTFM as long as you send along a link. I''ve got a pretty simple setup so far. Employee has_many PhoneNumbers. PhoneNumber belongs_to PhoneNumberType. When editing Employees I''d like to be able to also edit the PhoneNumbers and set their PhoneNumberTypes. Setting up the page to add/delete/show the PhoneNumbers was pretty simple, but editing them seems a bit trickier. The PhoneNumberType is set via a PopUp and the Number itself via a text_field. I''ve included the snipet below. I''m guessing this is pretty simple to fix, so if someone could spend a couple minutes and enlighten me as to what the right id value for the select and text should be and the "correct" way to set them? Thanks in advance, -- Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org) <% phoneNumberTypes = PhoneNumberType.find_all() %> <% @employee.phoneNumbers.each do |phoneNumber| %> <tr> <td> <select name="phoneNumber[phone_number_type_id]"> <% phoneNumberTypes.each do |phoneNumberType| %> <option value="<%= phoneNumberType.id %>"> <%= phoneNumberType.name %> </option> <% end %> </select> <td> <%= text_field ''phoneNumber'', ''number'' %> </td> <td> <%= link_to "delete", {:action => "deletePhoneNumber", :id => @employee.id, :phoneNumberID => phoneNumber.id }, :confirm => "Really delete #{phoneNumber.number}?" %> </td> </tr> <% end %>
Paul Haddad <paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:> Pardon me if this is in a FAQ somewhere, feel free to tell me to RTFM > as long as you send along a link.I''m a newbie and I don''t think I know the answer. But I''m going to bump this thread because it''s sufficiently simple I can follow it without having to setup a lot of stuff and be really smart. The one thing you didn''t say is why this code doesn''t work. How do you know it doesn''t work? One thing you might include is the HTML generated.> <% phoneNumberTypes = PhoneNumberType.find_all() %> > <% @employee.phoneNumbers.each do |phoneNumber| %> > <tr> > <td> > <select name="phoneNumber[phone_number_type_id]">You''ve included a ruby variable in straight text. Also, if it were to evaluate the ruby variable, you''d still end up with just a number i think. My guess is you want something like this: <select name="phoneNumber<%= phoneNumber[phone_number_type_id] %>"> That would generate a select box with the name "phoneNumber1" or "phoneNumber2" or something. Rails may have a better way to do this. Please, someone smart speak up.> <% phoneNumberTypes.each do |phoneNumberType| %> > <option value="<%= phoneNumberType.id %>"> > <%= phoneNumberType.name %> > </option> > <% end %> > </select> > <td> > <%= text_field ''phoneNumber'', ''number'' %>Same thing here with the name of your field I think. You''re going to get multiple text fields on the form for multiple numbers with not a very good way to tell them apart.> </td> > <td> > <%= link_to "delete", {:action => "deletePhoneNumber", :id => > @employee.id, :phoneNumberID => phoneNumber.id }, > :confirm => "Really delete #{phoneNumber.number}?" %> > </td> > </tr> > <% end %>-- doug-jGAhs73c5XxeoWH0uzbU5w@public.gmane.org
[snip]> <select name="phoneNumber[phone_number_type_id]"> > <% phoneNumberTypes.each do |phoneNumberType| %> > <option value="<%= phoneNumberType.id %>"> > <%= phoneNumberType.name %> > </option> > <% end %> > </select>[snip] The easiest way for this is: <%= collection_select("phoneNumber", "phone_number_type_id", phoneNumberTypes, "id", "name") %> then the associations get automagically populated. -- Cheers Koz
Koz, On Thu, 17 Mar 2005 08:26:59 +1300, Michael Koziarski <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> <%= collection_select("phoneNumber", "phone_number_type_id", > phoneNumberTypes, "id", "name") %> > > then the associations get automagically populated.That''s actually not quite enough, it''ll show the popup types but it won''t get/set the value on the phone number object. The only way I have got things to work is with the below code, which works but there''s got to be an easier way. -- Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org) <input name="employeePhoneNumbers[<%=count%>][number]" size="30" type="text" value="<%= phoneNumber.number %>" /> Employee.transaction do EmployeePhoneNumber.transaction do @employee.update_attributes(@params[''employee'']); @employee.employeePhoneNumbers().each_index { | index | employeePhoneNumber = @employee.employeePhoneNumbers[index]; employeePhoneNumber.update_attributes(@params[''employeePhoneNumbers''][index.to_s]); } end end
Paul Haddad wrote:> Koz, > > On Thu, 17 Mar 2005 08:26:59 +1300, Michael Koziarski > <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >><%= collection_select("phoneNumber", "phone_number_type_id", >> phoneNumberTypes, "id", "name") %> >> >>then the associations get automagically populated. > > That''s actually not quite enough, it''ll show the popup types but it > won''t get/set the value on the phone number object.Do you have an instance variable @phoneNumber? That''s what stumped me for the longest time. Here''s my example. Note that I have to explicitly set @topic before using "topic" in collection_select: form("question") do | form | @topic = @question.topic form << content_tag("b", "Topic") form << collection_select("topic", "id", @topics, "id", "name") form << tag("br") + tag("br") end The form method is fun; it takes a block that lets you append form fields. Jim -- Jim Menard, jimm-Xhj3G7Rj6JI@public.gmane.org, http://www.io.com/~jimm "This looks like a job for Legal Tender!" -- The Tick
Jim, On Wed, 16 Mar 2005 15:33:46 -0500, Jim Menard <jimm-Xhj3G7Rj6JI@public.gmane.org> wrote:> Do you have an instance variable @phoneNumber? That''s what stumped me for the > longest time. Here''s my example. Note that I have to explicitly set @topic > before using "topic" in collection_select:Employee has a too many to PhoneNumber, so a simple instance variable isn''t enough. The to one type associations are pretty simple to deal with, its the too many that seems to be a little trickier. -- Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org)
Paul,> Employee has a too many to PhoneNumber, so a simple instance variable > isn''t enough. The to one type associations are pretty simple to deal > with, its the too many that seems to be a little trickier.Sorry; I should have read your original post more closely. Jim -- Jim Menard, jimm-Xhj3G7Rj6JI@public.gmane.org, http://www.io.com/~jimm "This looks like a job for Legal Tender!" -- The Tick
On Wed, 16 Mar 2005 14:18:08 -0600, Paul Haddad <paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Koz, > > On Thu, 17 Mar 2005 08:26:59 +1300, Michael Koziarski > <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > <%= collection_select("phoneNumber", "phone_number_type_id", > > phoneNumberTypes, "id", "name") %> > > > > then the associations get automagically populated. > That''s actually not quite enough, it''ll show the popup types but it > won''t get/set the value on the phone number object.Right, collection select works with a belongs_to, I didn''t realise you have a has many. So to restate your problem. An employee has many phone numbers, phone numbers belong to a PhoneNumberType. You want to edit the employee & their phone numbers & their types in one page?> The only way I have got things to work is with the below code, which > works but there''s got to be an easier way. > -- > Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org) > > <input name="employeePhoneNumbers[<%=count%>][number]" size="30" > type="text" value="<%= phoneNumber.number %>" /> > > Employee.transaction do > EmployeePhoneNumber.transaction do > @employee.update_attributes(@params[''employee'']); > @employee.employeePhoneNumbers().each_index { | index | > employeePhoneNumber = @employee.employeePhoneNumbers[index]; > employeePhoneNumber.update_attributes(@params[''employeePhoneNumbers''][index.to_s]); > } > end > end >-- Cheers Koz
Koz, On Thu, 17 Mar 2005 09:59:33 +1300, Michael Koziarski <koziarski-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> So to restate your problem. An employee has many phone numbers, phone > numbers belong to a PhoneNumberType. You want to edit the employee & > their phone numbers & their types in one page? > >Yes exactly I thought I had written that on my original post, but certainly not as concisely as you did. -- Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org)
>> So to restate your problem. An employee has many phone numbers, phone >> numbers belong to a PhoneNumberType. You want to edit the employee & >> their phone numbers & their types in one page?I think something like this would work: View: <% @employee.phone_numbers.each do |@phone_number| %> <%= collection_select "phone_number[]", "phone_number_type_id", PhoneNumberType.find_all, :id, :name %> <%= text_field "phone_number[]", "number" %> <% end %> Controller: @employee.phone_numbers.each_with_index do |phone_number, idx| phone_number.update_attributes(@params[:phone_number][idx]) end P.S.: The Ruby naming convention for variables is underscored, not camel case. -- David Heinemeier Hansson, http://www.basecamphq.com/ -- Web-based Project Management http://www.rubyonrails.org/ -- Web-application framework for Ruby http://www.loudthinking.com/ -- Broadcasting Brain
David, First thanks for the reply. I did get the code to work with one change, but I do have a couple questions. On Thu, 17 Mar 2005 12:24:59 +0100, David Heinemeier Hansson <david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org> wrote:> <% @employee.phone_numbers.each do |@phone_number| %> > <%= collection_select "phone_number[]", "phone_number_type_id", > PhoneNumberType.find_all, :id, :name %> > <%= text_field "phone_number[]", "number" %> > <% end %> > > Controller: > @employee.phone_numbers.each_with_index do |phone_number, idx| > phone_number.update_attributes(@params[:phone_number][idx]) > endFirst I had to change phone_number.update_attributes(@params[:phone_number][idx]) to phone_number.update_attributes(@params[:phone_number][phone_number.id]) Now on the view I don''t understand how the phone_number[] construct becomes phone_number[phone_number.id], can you explain that? Also on the view why use the instance variable on the each loop as opposed to using a local var? Is it just to make the text_field and collection_select construct work? Any plans on changings things so that updating an object''s attributes follows through and updates its associations as well if they are referenced? What I mean is that instead of doing the above updates, setting the name like employee[phone_number][id][number], then the employee update would be smart enough to start a transaction and follow through by updating the phone_numbers as well. -- Paul Haddad (paul.haddad-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org paul-lcDEGG4I66s@public.gmane.org)