21
votes

I'm having an error with my routes/resources and controllers.

I have the following in the routes.rb:

# routes.rb
resources :users do  
  resource :schedule  
end

And I have a schedule_controller.rb inside controllers/users/ set up as I think it should be:

class Users::ScheduleController < ApplicationController

  # Controller methods here...

end

Running a rake:routes shows

user_schedule      POST   /users/:user_id/schedule(.:format)       schedules#create
new_user_schedule  GET    /users/:user_id/schedule/new(.:format)   schedules#new
edit_user_schedule GET    /users/:user_id/schedule/edit(.:format)  schedules#edit
                   GET    /users/:user_id/schedule(.:format)       schedules#show
                   PUT    /users/:user_id/schedule(.:format)       schedules#update

However, navigating to /users/:user_id/schedule is returning the following error:

uninitialized constant SchedulesController

My only thoughts on what the problem could be are that is has something to do with nested resources or declaring a single resource and I'm going wrong somewhere.

I'm using the helper

new_user_schedule_path(current_user)

when linking to my 'new' view.

4
Observe that ScheduleController is not SchedulesController. - matt
I arrived at this question searching for the error in the title but not having the nested vs namespaced resource problem. In my case the controller file was not placed in the correct folder. - stralsi
In my case the controller filename was not in the correct format. The filename should be "schedules_controller.rb" - amayer171292591

4 Answers

20
votes

It should be SchedulesController, not Users::ScheduleController. Controllers should only be namespaced when the route is namespaced with namespace. Controller names should also always be plural.

What you're creating is a nested resource, not a namespaced one.

5
votes

Is the namespacing of the SchedulesController intentional? i.e. do you really mean to do this?

class Users::SchedulesController < ApplicationController

Or are you only doing that because schedules are a "sub-thing" from users?

The reason I ask this is because typically within Rails, nested resource controllers aren't namespaced. You would only namespace a controller if you wanted to modify the controllers in a special way under a namespace. A common example of this would be having some controllers under an admin namespace, inheriting from a BaseController within that namespace that would restrict only admins from acessing those controllers.

Option 1

If you didn't intentionally namespace this controller, then you want to remove the Users:: prefix from your controller, and move it back to app/controllers/schedules_controller.rb, the helpers back to app/helpers/schedules_helper.rb and the views back to app/views/schedules. Perhaps you ran a generator which also generated a Users::Schedule model, which should also need to be renamed to Schedule and moved back to app/models/schedule.rb.

Option 2

If you did intentionally namespace this controller, then you want to do this in your routes:

namespace :users do
  resources :schedules
end

Leave everything that's been generated as it should be.

4
votes

In your routes.rb you need to specify the controller like this:

resources :users do
  resource :schedules, controller: 'users/schedules'
end
0
votes

replace resources :users to namespace :users

Because your schedule controller is inside users folder. class Users::ScheduleController < ApplicationController # Controller methods here... end