Search code examples
ruby-on-railsmethodsnested-resources

Rails "NoMethodError" with sub-resources


I'm a newbie Rails developer who is getting the following error when trying to access the 'new' action on my CityController:

undefined method `cities_path' for #<#<Class:0x104608c18>:0x104606f08>
Extracted source (around line #2): 
1: <h1>New City</h1>
2: <%= form_for(@city) do |f| %>
3:   <%= f.error_messages %>
4: 
5:   <div class="field">

As some background, I have a State model with many Cities. I'm getting this error after clicking on the following link coming from a State show page:

<p>Add a city: <%= link_to "Add city", new_state_city_path(@state) %></p>

When I run 'rake:routes' it says this is a legit route...

For more background, here is the CityController 'new' action:

def new
@city = City.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @city }
end
end

Here is the (complete) form in the view:

<%= form_for(@city) do |f| %>
<%= f.error_messages %>

<div class="field">
  <%= f.label :name %><br />
  <%= f.text_field :name %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

This initially made me think that it's a resources/routes issue since it came back with a mention of 'cities_path' (in fact, that's what another person posting to Stack Overflow had wrong (Rails error "NoMethodError" - My first ruby app). However, that doesn't seem to be the case from what I can see. Here are how my resources look in my routes file:

resources :states do
  resources :cities
end

I can get it working when they are not sub-resources, but I really need to keep them as sub-resources for my future plans with the app. Any help would be very much appreciated, since I've been racking my brains on this for more hours than I would care to admit... Thanks!

(Not sure this matters at all, but I'm running the very latest version of Rails 3 beta2).


Solution

  • Your problem is coming from line 2 of your view above, specifically the form_for declaration. As you pointed out, state_city_path is a valid path, but right now, your form is not using this path, it's using city_path. When using nested resources, you need to define everything in terms of that nesting. Your form_for should look something like form_for([@state, @city]) do (I don't remember the exact syntax).

    Your follow up answer will work, but isn't exactly the best way to go about it, unless you want to be able to look at cities that are not in the context of a state.

    Hope this helps.

    PS. The form_for documentation is pretty good, and shows some good examples when using it with resources.