3

When I go to the path: /genre/new in my application I get this error:

myapp/app/views/genre/_form.html.erb where line #1 raised:
undefined method `genres_path' for #<#<Class:0x007fdcb39edcb0>:0x007fdcb39e8080>

However when I go to /genre/:id/edit the _form.html.erb file renders without error and the record is updated with no problems.

My new.html.erb and edit.html.erb files call <%= render 'form' %> and my _form.html.erb file has:

<%= form_for(@genre) do |f| %>
    <%= f.label :title %> <br />  <%= f.text_field :title %>
    <%= f.label :desc %>  <br />  <%= f.text_field :desc %>
    <%= f.submit %>
<% end %>

In genre_controller.rb my 'new' and 'edit' actions are as follows:

  def new
    @genre = Genre.new
    current_user.authorize! :create, @genre  # cancan authorization

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @genre }
    end
  end

  def edit
    @genre = Genre.find(params[:id])
    current_user.authorize! :update, @genre   # cancan authorization
  end

I've run a search in my codebase for the string "genres" and the only place it occurs is in the logs, so I'm sure this is not a typo in my code.

My guess is that Rails routing system correctly pluralizes "genre" to "genre", but form_for (or a dependency) is creating the pluralization "genres", but only when the parameter passed to it is empty or "new".

Given the error is around 'genres_path', I tried various combinations of the following in my routes.rb file, but they didn't solve the problem:

  match "/genres" => "genre#index", :as => :genre
  match "/genres/:id(.:format)" => "genre#show", :as => :genre
  match "/genre" => "genre#index", :as => :genres
  match "/genre/:id(.:format)" => "genre#show", :as => :genres

Any thoughts on how I can work around this?

EDIT: Here are the routes generated by the resources :genre statement in my routes.rb file:

genre_index GET    /genre(.:format)           {:action=>"index", :controller=>"genre"}
            POST   /genre(.:format)           {:action=>"create", :controller=>"genre"}
  new_genre GET    /genre/new(.:format)       {:action=>"new", :controller=>"genre"}
 edit_genre GET    /genre/:id/edit(.:format)  {:action=>"edit", :controller=>"genre"}
      genre GET    /genre/:id(.:format)       {:action=>"show", :controller=>"genre"}
            PUT    /genre/:id(.:format)       {:action=>"update", :controller=>"genre"}
            DELETE /genre/:id(.:format)       {:action=>"destroy", :controller=>"genre"}
Don Leatham
  • 2,694
  • 4
  • 29
  • 41

1 Answers1

3

on new.html.erb try

<%= form_for(@genre, :url => genre_path, :method => :post) do |f| %>

assuming you have your route setup as a resource - resources :genre

also this will not work on edit.html.erb

http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for

Update:

this is the one we are interested in

POST   /genre(.:format)           {:action=>"create", :controller=>"genre"}

try this

<%= form_for(@genre, :url => {:action=>"create", :controller=>"genre"}, :method => :post) do |f| %>
house9
  • 20,359
  • 8
  • 55
  • 61
  • Thanks for the idea. I tried it and it leads to a different error: No route matches {:action=>"show", :controller=>"genre"}. But this is a bogus error - I have a route like that. When I run "rake routes" I get: genre GET /genre/:id(.:format) {:action=>"show", :controller=>"genre"} The exact route the error message say's I'm missing. Any idea what is causing this? – Don Leatham Mar 25 '12 at 16:07
  • 1
    can you add the output from rake routes for all of the genre routes - also see updated answer - specify the method as put or post – house9 Mar 25 '12 at 16:46
  • See my routes in the question, at the bottom. Tried both :put and :post as :methods - same error as before ("no route matches...") Also, tried a few things I saw in the docs, but no success. This really has me stumped. Appreciate your help. – Don Leatham Mar 25 '12 at 18:31
  • I tried your last set of arguments for form_for with no success. Looking at multiple dictionaries, I've seen that "genres" is an acceptable pluralization. So I decided not to fight Rails on this issue. I went back and changed the names of my controller, helper, and db table, as well as some link_to statements. It all works now. I guess the moral of the story is: never fight Rails on pluralization - you will loose in the end. Thanks again for your help. – Don Leatham Mar 25 '12 at 19:41
  • I had a similar problem that had nothing to do with plurals. I was using a non-namespaced model class (Book) with a namespaced (Admin) controller, so the resource based route is declared as "namespace :admin do resources :books end". The correct path for the index named route is then "admin_books_path". However, as explained in the link provided in this answer, form_for(@book) will take the path to be just "books_path", so I had to override the :url, writing "form_for(@book, :url => admin_books_path)", to get things to work. – Jan Hettich Jul 09 '12 at 10:47