views:

292

answers:

3

OK, so the relationship is: Program has many :events And each Event belongs to an Organizer (who has_many :events)

In a form for Program/edit, I'd like to list the associated events, and with each of those entries, also have access to each Organizer so I can do something like:

textfield(event.name) | textfield(event.date) | label(event.organizer.name)

So...

<% form_for([:admin, program]) do |f| %>

...

  <h3>Event Data Fields</h3>
    <table>
     <% f.fields_for :events do |event_form| %>
  <tr class="line_item">
    <td><%= event_form.text_field :name %></td>
    <td><%= event_form.text_field :date %></td>
    <td><%= event_form.text_field "organizer.name", :disabled=>true %></td>

  </tr>


      <% end %>
    </table>
    <p><%= f.submit "Submit" %></p>
<% end %>

Obviously, event_form.text_field "organizer.name" won't work, but that's the concept

A: 

Rails form helpers only work if you are working on one object at a time. If you want to update attributes of other records at the same time, you need to use text_field_tag for those fields, and include custom logic in the controller for interpreting/saving that data. IMHO, this is far from best practice.

Alternate solutions include using AJAX inline-editing, or if the idea is to be able to associate organizers with events when editing, to use a select field.

However, if organizers are so closely tied to events in your domain that you would want to edit their fields at the same time, why not just have organizer_name on your event object? At least, that would be my instinct without knowing more about your object model.

floyd
well actually, I just want to show the organizer's name...not necessarily update its attributes, which I understand would be a bit more complciate dof a form
Zando
You don't need custom logic. Now when Rails support nested forms it can do for you whole "custom logic". You can nest it in many levels and can create really complex forms. Of course there are situations where default approach doesn't work, but it works in most cases.
klew
+2  A: 

Why not just use fields for?...

<% form_for([:admin, program]) do |f| %>

...

  <h3>Event Data Fields</h3>
  <table>
     <% program.events.each do |event| %>
       <% f.fields_for event do |event_form| %>
  <tr class="line_item">
    <td><%= event_form.text_field :name %></td>
    <td><%= event_form.text_field :date %></td>
    <% event_form.fields_for(:organizer) do |organizer_form| %>
      <td><%= organizer_form.text_field :name, :disabled=>true %></td>
    <% end %>
  </tr>
       <% end %>
     <% end %>
   </table>
   <p><%= f.submit "Submit" %></p>
<% end %>
halogenandtoast
Well, that seemed to work, as long as I add a accepts_nested_attributes_for :organizer to the Event model
Zando
@Zando: in my example you don't have to use `fields_for` and `accepts_nested_attributes_for` :)
klew
+1: Much nicer than my try! :)
Veger
A: 

You can do it as halogenandtoast mentioned but if you would like only to show that field, you can also do it like this:

Instead of:

<td><%= event_form.text_field "organizer.name", :disabled=>true %></td>

put:

<td><%= event_form.object.organizer.name %> </td>

When you add object to form builder it will refer to processed object, so you can access it's attributes.

klew