简体   繁体   中英

Rails 4: routing for has_many :through association

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:

  • Access a list of all their calendars at: http://localhost:3000/users/:id/calendars
  • Access each of their calendar at http://localhost:3000/users/:id/calendars/:id
  • For a given calendar, access a list of all the users of this calendar (but here I am not sure which URL would make sense).

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM