jdotjdot
jdotjdot

Reputation: 17082

Rails undefined method `user_index_path`

I'm new to Ruby and Rails and working my way through the Rails Tutorial. Early on, I realized that I accidentally created my model as Users rather than User, so I've been going with that ever since.

It hasn't been an issue until I tried to implement the sign up page, and now whether going to pages or running the test visit signup_path for the sign up page, I keep getting the following error:

undefined method `users_index_path' for #<#<Class:0x007f9e3e1d91b8>:0x007f9e3e1d1ff8>

I can't figure out what's going wrong here. When I run rake routes I get the following:

~/Coding/rails_projects/sample_app (sign-up*) ☔  rake routes
   Prefix Verb   URI Pattern               Controller#Action
    users GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
 new_user GET    /users/new(.:format)      users#new
edit_user GET    /users/:id/edit(.:format) users#edit
     user GET    /users/:id(.:format)      users#show
          PATCH  /users/:id(.:format)      users#update
          PUT    /users/:id(.:format)      users#update
          DELETE /users/:id(.:format)      users#destroy
     root GET    /                         static_pages#home
     help GET    /help(.:format)           static_pages#help
    about GET    /about(.:format)          static_pages#about
  contact GET    /contact(.:format)        static_pages#contact
   signup GET    /signup(.:format)         users#new

From that output, it looks to me like there should be a method users_index_path.

If it helps, my Users controller is the following:

class UsersController < ApplicationController
  def new
    @user = Users.new
  end

  def show
    @user = Users.find(params[:id])
  end
end

Using Rails 4.0.5.

Output from a page giving me the error:

enter image description here

Please keep in mind users_index_path is being called by Rails and not by me.

Upvotes: 0

Views: 1141

Answers (1)

tompave
tompave

Reputation: 12427

with

users GET    /users(.:format)          users#index
      POST   /users(.:format)          users#create

you'll have a users_path method that will generate the /users path. That path will lead to either the index action (with a GET request) or the create action (with a POST request).

Under the hood, form_for @user will call the users_path method and set things up to fire a POST on submit (when @user is a new record). The URL helper method is calculated dynamically from the class name. This is ok if you're using Rails' defaults, but if you've defined custom routes you'll need to specify the URL explicitly.

With this out of the way, let's look at your problem.

A model with a plural name, e.g. class Users, will confuse rails.
When you pass @user to form_for, Rails will look at the class name, notice that it's a plural word, and try its best to deal with the ambiguity.
Normally it would be user_path for singular routes (show, update, delete) and users_path for the plural ones (index, create). Here, however, users_path must be used for the singular routes, and Rails will fallback to use users_index_path for index and create.

This would be all right.... but you have defined the routes using the default statement, probably with something like

resources :users

Which is correct, but not compatible with your model name.

Either rename your routes (bad) or rename your model (good).

Upvotes: 3

Related Questions