Friday, January 26, 2007

Rails Routing Errors: The "diff:{}" Problem

Rails error messages are generally pretty good, but like anything, every once in a while you get one that just makes you go nuts. In creating a new section of our application, I decided to go the RESTy route and use the shiny new magic url thingies. To make life even more interesting, I used nested resources. In particular, I set up one route like this:



map.resources :calls,
:path_prefix => 'call_center',
:controller => 'call_center/calls',
:member => { :close => :get } do |call|
call.resources :call_notes,
:controller => 'call_center/call_notes',
:new => {:add_note => :post}
end


Unfortunately, I immediately got this error when I tried to use my new route:



add_note_new_call_note_url failed to generate from
{:action=>"add_note",
:controller=>"call_center/call_notes"},
expected:
{:action=>"add_note",
:controller=>"call_center/call_notes"},
--> diff: {} <--



Notice the last line: diff: {}. So the difference between what the routing system got and what it wanted was….nothing. The answer, which I found after much gnashing of teeth, turned out to be really simple. I needed to add a parameter to the add_note_new_call_note_url. The call that generated the error was




<% remote_form_for :call_note,
:url => add_note_new_call_note_url, ...




What it needed to be was




:url => add_note_new_call_note_url(@call), ...



The @call provides the url generator with the correct context. I had seen (and used) this parameterized url helper in other places, but had not added it here. In fact, I'm still a little fuzzy on when exactly its needed, since some examples (even in AWDWR) don't use it and some do. At any rate, I now have a first place to look when I get this odd error message again. Lesson learned (I hope…)

No comments: