Rails 4:has_many 的路由:通过关联
Rails 4: routing for has_many :through association
我有三个模型:
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
当我简单地使用以下路由时:
resources :users
resources :administrations
resources :calendars
一切正常,意味着我可以访问
http://localhost:3000/users
http://localhost:3000/administrations
http://localhost:3000/calendars
和每个模型的 CRUD 实例。
但这不是我想要达到的。
我想要的是允许用户:
- 访问他们所有日历的列表:
http://localhost:3000/users/:id/calendars
- 在
http://localhost:3000/users/:id/calendars/:id
访问他们的每个日历
- 对于给定的日历,访问该日历的所有用户的列表(但在这里我不确定哪个 URL 有意义)。
所以我想我需要更新我的路线。
这是我尝试过的:
解决方案 1
resources :users do
resources :administrations
resources :calendars
end
但是,当我访问 http://localhost:3000/users/1/calendars
时,出现以下错误:
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 %>
解决方案 2
concern :administratable do
resources :administrations
end
resources :users, concerns: :administratable
resources :calendars, concerns: :administratable
但是,当我访问 http://localhost:3000/users/1/calendars
时,出现以下错误:
Routing Error
No route matches [GET] "/users/1/calendars"
我肯定遗漏了一些明显的东西 — 抱歉,我对 Rails 不是很有经验 — 但我不知道为什么。
知道我应该如何嵌套我的资源吗?
方案1是我会采用的方式。问题是当你嵌套资源时,它会导致 helpers 发生变化(你可以通过 运行 rake routes
看到这一点)。正确的辅助方法是 new_user_calendar_path
所以改变
<%= link_to 'New Calendar', new_calendar_path %>
到
<%= link_to 'New Calendar', new_user_calendar_path(@user) %>
其中 @user 在控制器中设置为指向正确的用户。
奖金
您还可以查看 shallow routes(该页面的第 2.7.2 节)。它们提供了一种更简洁的方式来调用带有 URL
的嵌套日历
GET /calendars/:id
而不是
GET /users/:userId/calendars/:calendarId
因为 calendarId 无论如何都是唯一的。
我有三个模型:
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
当我简单地使用以下路由时:
resources :users
resources :administrations
resources :calendars
一切正常,意味着我可以访问
http://localhost:3000/users
http://localhost:3000/administrations
http://localhost:3000/calendars
和每个模型的 CRUD 实例。
但这不是我想要达到的。
我想要的是允许用户:
- 访问他们所有日历的列表:
http://localhost:3000/users/:id/calendars
- 在
http://localhost:3000/users/:id/calendars/:id
访问他们的每个日历
- 对于给定的日历,访问该日历的所有用户的列表(但在这里我不确定哪个 URL 有意义)。
所以我想我需要更新我的路线。
这是我尝试过的:
解决方案 1
resources :users do
resources :administrations
resources :calendars
end
但是,当我访问 http://localhost:3000/users/1/calendars
时,出现以下错误:
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 %>
解决方案 2
concern :administratable do
resources :administrations
end
resources :users, concerns: :administratable
resources :calendars, concerns: :administratable
但是,当我访问 http://localhost:3000/users/1/calendars
时,出现以下错误:
Routing Error
No route matches [GET] "/users/1/calendars"
我肯定遗漏了一些明显的东西 — 抱歉,我对 Rails 不是很有经验 — 但我不知道为什么。
知道我应该如何嵌套我的资源吗?
方案1是我会采用的方式。问题是当你嵌套资源时,它会导致 helpers 发生变化(你可以通过 运行 rake routes
看到这一点)。正确的辅助方法是 new_user_calendar_path
所以改变
<%= link_to 'New Calendar', new_calendar_path %>
到
<%= link_to 'New Calendar', new_user_calendar_path(@user) %>
其中 @user 在控制器中设置为指向正确的用户。
奖金
您还可以查看 shallow routes(该页面的第 2.7.2 节)。它们提供了一种更简洁的方式来调用带有 URL
的嵌套日历GET /calendars/:id
而不是
GET /users/:userId/calendars/:calendarId
因为 calendarId 无论如何都是唯一的。