views:

637

answers:

4

I have created a form that needs to show data from 2 tables (parent and child). When the form is submitted only the child fields are updated (the parent fields are meant to be display only). While the parent model fields are displayed these need to be protected from updates (preferably via the formbuilder, rather than via css).

FWIW this is a pretty common master/detail use case. However I have not been able to find any examples of this - most of the examples I've seen seem to be trivial/single model display/update where all displayed fields are updateable).

Any ideas/samples/suggestion/tutorials/examples of real world, multi model Rails forms would be helpful.

TIA

+1  A: 

Just out of interest, why bother going through the motions of creating a multi-model form when you only want to update the child record? My advice would be keep your form simple, I.e. make it a child form and just display the data from the parent record. If needs be, you could even style that display to look like part of the form, although I think that may throw the user off.

If you really need to do what you are doing, I would still use CSS to disable/readonly the input fields and in your controller update action, only pass the attributes you want to update into the update_attributes method call.

Finally, maybe look into the attr_protected method to prevent the fields you may want protecting from accidental mass-assignment.

tsdbrown
OK - A child form which displays data from a parent is what I was after here (maybe I phrased the question poorly?). However I'm still unclear re how to make the parent record fields read only- AFAIK by default form builder creates input fields for all model fields. An example would be helpful here.
BrendanC
Can you show me your current 'form builder' code. I am still a little confused about what you mean. If your are creating the form you can have whatever fields you see fit.
tsdbrown
A: 

I agree with tsdbrown, I don't think a complex form is required. If you'd like to learn more about complex forms or you really have your heart set on using a complex form I'd recommend watching the Railscasts episodes (73 - 75).

Andy Gaskell
A: 

As tsdbrown said before, you are adding a complexity layer to your forms that's not need. If all you want is to update a detail model, while showing some info of it's parent, you could just do so with something like:

Order number: <%= @line_item.order.number %>
 Order date: <%= @line_item.order.order_date %>

 <% form_for @line_item do |f| %>
   <%= f.label :quantity %>
   <%= f.text_edit :quantity %>
 <% end %>

When you'd like to edit both, then you can research on the field_for and nested forms methods (the Railscasts suggestion mentioned before it's great).

Yaraher
A: 

Thx for the responses which helped resolve my problem/question. Just want to close this out in case it helps others in the future.

Turns out I had been getting an error trying to reference my parent data element (patients.lname) as it was being passed in an array of results, rather than as a single result. In my view controller I had:

 @visit = Visit.all(:select => "visits.id, visits.visittype, visits.visitdate, events.patient_id, patients.lname",
  :conditions => ["visits.id = ?",params[:id] ],
  :joins => "INNER JOIN events on events.id = visits.event_id INNER JOIN patients on patients.id = events.patient_id" )

In my view I had (this was giving me an invalid reference as I was doing a find all above):

Editing visit for patient : # should be

Below is the improved (and simpler) version where I find the specific record I need (basically replacing find all with find first):

@visit = Visit.find(:first, :select => "visits.id, visits.visittype, visits.visitdate, events.patient_id, patients.lname", :conditions => ["visits.id = ?",params[:id] ], :joins => "INNER JOIN events on events.id = visits.event_id INNER JOIN patients on patients.id = events.patient_id" )

And in the view:

<% form_for(@visit, :builder => LabelFormBuilder) do |f| %> <%= f.error_messages %> Name: <%= @visit.lname %> <%= f.text_field :visittype %> <%= f.date_select :visitdate %>

<%= f.submit 'Update' %>

<% end %>

Sometimes it's hard to see the wood for the trees! Hope this helps someone else.

BrendanC