Reputation: 6897
I have three models:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
When I simply use the following routes:
resources :users
resources :administrations
resources :calendars
everything works, meaning that I can visit
http://localhost:3000/users
http://localhost:3000/administrations
http://localhost:3000/calendars
and CRUD instances of each model.
But this is not what I want to achieve.
What I want is to allow users to:
http://localhost:3000/users/:id/calendars
http://localhost:3000/users/:id/calendars/:id
So I figured I needed to update my routes.
Here is what I have tried:
SOLUTION 1
resources :users do
resources :administrations
resources :calendars
end
But then, when I visit http://localhost:3000/users/1/calendars
, I get the following error:
NameError in Calendars#index
Showing /Users/TXC/code/rails/calendy/app/views/calendars/index.html.erb where line #27 raised:
undefined local variable or method `new_calendar_path' for #<#<Class:0x007fb807e672d0>:0x007fb807e66510>
Extracted source (around line #27):
<br>
<%= link_to 'New Calendar', new_calendar_path %>
SOLUTION 2
concern :administratable do
resources :administrations
end
resources :users, concerns: :administratable
resources :calendars, concerns: :administratable
But then, when I visit http://localhost:3000/users/1/calendars
, I get the following error:
Routing Error
No route matches [GET] "/users/1/calendars"
I must be missing something obvious — sorry, I am not very experienced with Rails — but I cannot figure out why.
Any idea how I should nest my resources?
Upvotes: 3
Views: 2703
Reputation: 7405
The solution 1 is the way I would take. The problem is that when you nest the resources, it causes the helpers to change (you can see this by running rake routes
). The correct helper method is new_user_calendar_path
so change
<%= link_to 'New Calendar', new_calendar_path %>
to
<%= link_to 'New Calendar', new_user_calendar_path(@user) %>
where @user is set in the controller to point to correct user.
Bonus
You could also take a look at the shallow routes (section 2.7.2 in that page). They provide a cleaner way to call the nested calendars with URL
GET /calendars/:id
instead of
GET /users/:userId/calendars/:calendarId
since the calendarId is anyway unique.
Upvotes: 4