2015-10-26 61 views
1

我有基于用户角色的访问控制。用户有很多角色。 每个角色都可以访问一些控制器,操作和范围。Rails4从模型方法访问controller_name

我有方法can_control?(控制器)在用户模型中检查用户是否有权访问特定的控制器。我有类似的行动方法。

然后,在视图或控制器我可以使简单的逻辑使用隐藏某些信息或允许访问:

current_user.can_control?(controller_name) 

不知是否有可能创造在用户模型,其自动进行CONTROLLER_NAME方法。我试图在模型中定义方法。

def can_control? 
    self.permitted_cotrollers.include?(controller_name) 
end 

但它给我一个错误:

undefined local variable or method `controller_name' for #<User:0x007f00e8ceb928> 

我理解错误,但是可以找到解决办法,或者有可能有一个。

+0

我觉得你还是需要通过控制器的名称,因为can_control参数?是一种实例方法,您需要检查用户访问某个控制器的能力。每次您加载不同的视图时,Controller_name似乎也会更改。为了便于实施,您可以尝试使用:https://github.com/CanCanCommunity/cancancan –

+0

恐怕您没错。在这个例子中它很容易,但我需要更复杂的方法,我需要使用这个方法,并在每个方法中传递它并不像我想的那样干。 – rpeczykowski

+0

但我想如果你只是想控制访问你的视图和控制器,你可以尝试'cancancan' gem。我已经尝试了很多次,并且证明是有效的。 –

回答

0

这里使用的snake_case名字是我能想到的最好的解决办法:您可以访问当前的控制器名来自任何控制器方法的params[:controller]

在用户模式:

def can_control?(params) 
    self.permitted_controllers.include?(params[:controller]) 
end 

在任何控制器:

current_user.can_control?(params) 
+0

谢谢,我实现了这一点,并运行良好。这简化了我的申请。 – rpeczykowski

+0

不客气。我也希望你的'allowed_controllers'列表是你可以为用户组设置的,而不仅仅是为用户设置的。否则,有一天你可能很难维持系统。 – Caillou

0

在你的模型,你可以得到标准的使用相关的控制器名称:

"#{self.class.to_s}Controller" 
  • 自我是指你的模型
  • 的.class获得同级车
  • .to_s同级车转换为一个包含类名称的字符串

如果你需要它写在snake_case而不是CamelCase中,使用这个:

"#{self.class.to_s.tableize}_controller" 
  • .tableize模型的首字母大写的名字转换成你的控制器
+0

self.class在这种情况下总是返回UserController。我想在不同的控制器之间分享它。因此,例如在PostController或Post视图中,我可以使用白色: 'if can_control?',而不是'if can_control?(controller_name)'。 – rpeczykowski

+0

噢,好的。我以前不明白你的实际需要。我要写另一个答案。 – Caillou