2013-05-06 36 views
1

我有一个自定义路线设置中,将URL中的LOCATION_ID(见下文)Rails的康康舞 - 如何限制用户访问自定义URL路由

resources :menu_items, :path => "/location_menu/:location_id" 

所以,当我打/location_menu/1它会告诉我LOCATION_1菜单,/location_menu/2将显示location_2的菜单等

每个用户关联到多个位置(has_many :locations

我试图用康康舞从查看某些MENU_ITEM URLS限制用户。

例如:用户1与位置1相关联和2因此,他们只能查看页面/location_menu/1/location_menu/2。但他们无法查看/location_menu/3

我在控制器创建自定义方式作为的before_filter:

before_filter :location_check 
... 
def location_check 
    @location = Location.find(params[:location_id]) 
    authorize! :see_location, @location 
end 

在我ability.rb

can :see_location, MenuItem do |location| location && user.location_ids.include?(location.id) end 

出于某种原因,这并不为我工作。我可能做错了什么?如果你们能帮助我,我会非常感激!

谢谢。

+0

做'user'和'location'是之间的关联'has_many_through' – Viren 2013-08-01 09:57:23

回答

0

首先,我没有看到定义自定义路由而不是嵌套资源会带来哪些好处,但它看起来像是夸大了您的域语言,并导致可能引用任何特定资源的情况几个不同的名字 - 这可能会让人感到困惑,所以现在简化它是值得的。

在你location_check方法,您是在Location实例授权see_location,但你已经证明我们的Ability类的部分涉及MenuItem类。尝试定义你这样的能力:

can :see_location, Location, id: user.location_ids 

编辑

如果你需要一个康康舞行动直接授权MenuItems,试试这个(假设MenuItem一个belongs_to :location关系):

can :view, MenuItem, location_id: user.location_ids 

至于你的路线,想想更简单。所有你需要的是这样的:

resources :location_menus 

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

+0

嘿,这完全是有道理的。但是,我不是授权位置,而是根据他们的location_ids授权MenuItem。 – Rahul 2013-05-06 17:08:54

+0

因此,对于路线,你是否在想这样的事情? '资源:位置做 集合做 范围路径: “:ID” 做 资源:menu_item_locations 结束 结束 end' 这样的网址是/位置/ 1/MENU_ITEM /:ID。你如何锁定一个位置和menu_item id在同一时间? – Rahul 2013-05-06 17:14:05

+0

我已更新回答 - 是否更清晰? – 2013-05-06 17:37:16

1

在能力范围内检查一次。RB,

user.location_ids.each do |l| 
    can :view, MenuItem, location_id: l 
end 
相关问题