Ruby on rails Rails Cancan-如何限制用户访问自定义URL路由

Ruby on rails Rails Cancan-如何限制用户访问自定义URL路由,ruby-on-rails,ruby,rubygems,gem,cancan,Ruby On Rails,Ruby,Rubygems,Gem,Cancan,我有一个自定义路由设置,在url中有一个位置\u id(见下文) 所以当我点击/location\u menu/1时,它会显示location\u 1的菜单,/location\u menu/2会显示location\u 2的菜单,等等 每个用户都关联到多个位置(有多个:位置) 我试图使用cancan限制用户查看某些菜单项URL 例如:用户1与位置1和2关联。因此,他们只能查看页面/location\u menu/1和/location\u menu/2。但他们将无法查看/location\u菜

我有一个自定义路由设置,在url中有一个位置\u id(见下文)

所以当我点击
/location\u menu/1
时,它会显示location\u 1的菜单,
/location\u menu/2
会显示location\u 2的菜单,等等

每个用户都关联到多个位置(
有多个:位置

我试图使用cancan限制用户查看某些菜单项URL

例如:用户1与位置1和2关联。因此,他们只能查看页面
/location\u menu/1
/location\u menu/2
。但他们将无法查看
/location\u菜单/3

我在我的控制器中创建了一个自定义方法作为before\u过滤器:

before_filter :location_check
 ... 
def location_check
  @location = Location.find(params[:location_id])
  authorize! :see_location, @location
end
以我的能力.rb

can :see_location, MenuItem do |location| location && user.location_ids.include?(location.id) end
出于某种原因,这对我不起作用。我可能做错了什么?如果你们能帮我,我会非常感激的


谢谢。

首先,我不知道定义自定义路由而不是嵌套资源有什么好处,但它看起来像是在膨胀你的域语言,导致一种情况,任何特定的资源都可能被几个不同的名称引用——这可能会变得足够混乱,现在值得简化

在您的
location\u check
方法中,您正在对
location
实例授权
see\u location
,但您向我们展示的
能力
类的部分涉及
MenuItem
类。试着这样定义你的能力:

can :see_location, Location, id: user.location_ids
编辑

如果您需要cancan操作来直接授权
菜单项
,请尝试此操作(假设
属于
菜单项
上的:位置
关系):

至于你的路线,想得更简单些。您所需要的就是:

resources :location_menus

…然后与此相关的所有内容都进入
位置菜单控制器
。不要担心没有同名的模型-您仍然可以使用
Location.find(params[:id])
查找您的位置。据我所知,位置菜单页面的所有内容都取决于当前用户对特定位置的访问,因此您可以首先将
LocationMenu
视为一种围绕
location
的虚拟资源,我不知道定义自定义路由(而不是嵌套资源)会给您带来什么好处,但它似乎会使您的域语言膨胀,并导致任何特定资源都可能被几个不同的名称引用的情况——这可能会变得足够混乱,值得现在简化

在您的
location\u check
方法中,您正在对
location
实例授权
see\u location
,但您向我们展示的
能力
类的部分涉及
MenuItem
类。试着这样定义你的能力:

can :see_location, Location, id: user.location_ids
编辑

如果您需要cancan操作来直接授权
菜单项
,请尝试此操作(假设
属于
菜单项
上的:位置
关系):

至于你的路线,想得更简单些。您所需要的就是:

resources :location_menus

…然后与此相关的所有内容都进入
位置菜单控制器
。不要担心没有同名的模型-您仍然可以使用
Location.find(params[:id])
查找您的位置。据我所知,位置菜单页面的所有内容都取决于当前用户对特定位置的访问,因此您可以将
LocationMenu
视为一种围绕
location

在ability.rb中检查一次的虚拟资源

user.location_ids.each do |l|
  can :view, MenuItem, location_id: l
end

在ability.rb内检查一次

user.location_ids.each do |l|
  can :view, MenuItem, location_id: l
end

嘿,这完全有道理。然而,我并没有授权位置,而是根据它们的位置ID授权菜单项。那么对于路线,您是否想过这样的事情
resources:locations do collection do scope path::id“do resources:menu_item_locations end
所以URL应该是/locations/1/menu_item/:id。您如何同时锁定位置和菜单项id?我想是的,今天晚些时候我会尝试一下,让您知道!嘿,这完全有道理。然而,我并没有授权位置,而是根据它们的位置ID授权菜单项。那么对于路线,您是否想过这样的事情
resources:locations do collection do scope path::id“do resources:menu_item_locations end
所以URL应该是/locations/1/menu_item/:id。您如何同时锁定位置和菜单项id?我想是的,今天晚些时候我会尝试一下,让您知道!
用户
位置
之间的关联是否为
用户
位置
之间的关联是否为
位置