Cannot grok form_for

I’m stumped with form_for(). I’ve RTFM’d until my eyeballs have bled.
I’ve looked over examples. I still don’t get it, and each thing I try
leads to some other error. If someone can lead me to form_for
enlightenment, I’d be in your debt.

I’m using RESTful, shallow routing: one User :has_many Reports.
A Report has three fields of importance:
– user_id (its parent)
– location_id (reference to a Location record)
– report_type (“graph” or “chart”)

I’m trying to write a _report.html.erb partial that does double duty: it
can fill in fields of a new report (report.new_record? => true) as well
as update fields of an existing report (report.new_record? => false).

The _report partial receives two inputs: report is the current report
(either new or extant), and @user is set to the owning user.

The form_for needs present the user with [location_id] and [report_type]
fields (eventually to be replaced by pull_down lists), and needs to
silently fill in the [user_id] field of the report. Then, upon
form.submit(), it needs to ‘POST user_reports_path(@user.id)’ for new a
report, or ‘PUT report_path(report.id)’ for updating a report.

But even my basic attempts get an error message, and I’m not sure why:

<% form_for(:report, report, :url => {:action => “update”}) do |f| %>

gets an error

ActionView::TemplateError (No route matches {:action=>“update”}) on line
#12 of app/views/reports/_report.html.erb

My reports_controller.rb does have an update method. Perhaps because
it’s not using the HTTP PUT method? If so, how do you specify which
HTTP method gets invoked when you click on the form.submit button?

I feel like a wimp for even asking, but can someone give me a sketch of
what the form_for might look like here?

Many thanks.

  • ff

Okay, some elucidation:

The following works when report.new_record? is true, fails when
report.new_record? is false:

form_for([@user, report])

because it’s trying to call the undefined function ‘user_report_path’.
(Of course it’s undefined – I’ve specified shallow routing!) So
perhaps @Alex’s comment of Form_for with nested shallow route - Rails - Ruby-Forum is
relevant here.

So if I modify my form_for for the new_record vs non-new_record, it
looks like this (yech):

<% form_for((report.new_record?)?([@user, report]):(report)) do |f| %>
<%= f.submit ‘JumpUpAndDown’ %>
<% end %>

Aside from looking pretty nasty, the generated HTML is a bit suspicious:
Shouldn’t it be a POST method when report.new_record? is true and a PUT
method when report.new_record? is false?

Generated for report.new_record? == true:

Generated for report.new_record? == false:

What am I missing here?

  • ff