从模型中访问current_user最优雅的方法是什么?或者为什么这是个坏主意?

时间:2012-06-12 22:05:34

标签: ruby-on-rails ruby activerecord

所以,我在我的用户和用户修改的对象之间实现了一些权限..我想减少视图/控制器与模型之间的耦合(调用所述权限)。为此,我有一个想法:在before_save / before_create / before_destroy回调中实现一些权限功能。但由于权限与用户(current_user.can_do_whatever?)绑定,我不知道该怎么做。

这个想法甚至可能会增加耦合,因为current_user具体是控制器级别。

我最初想要这样做的原因是: 在我的控制器上,我必须检查用户是否能够save / create / destroy。那么,为什么不在save / create / destroy之后返回false,就像rails .save已经做的那样,并向模型对象添加错误并返回false,就像rails的验证?

Idk,这是好还是坏?有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

让控制器检查用户的权限。要让模型处理授权逻辑会导致更多耦合(只是在不同的地方,并且仍然会耦合到控制器以获取当前用户)。检查权限实际上不是模型的内部逻辑。

Simile:想象一下,如果文件有责任检查是否可以读取/写入,而不是让操作系统(所有控制器的母亲)真正处理访问。

如果你想要更清洁的控制器,你可以(例如)制作一些通用的before_filters,根据当前用户限制对CRUD操作的访问。

答案 1 :(得分:2)

Flambino给了你派对线:)但是让我加上我的2美分。 当然可以将访问控制逻辑视为模型的一部分。

模型验证是一种检查操纵用户对crud操作的权限的方法。这样做的一个缺点就是访问逻辑通常会在模型之间进行推广,因此我们喜欢​​将它们抽象出来,就像在一个整洁的cancan能力文件中一样。

你可以通过让你的操作本身成为模型上的多态关联来实现你的蛋糕并吃掉它。这就是大多数审计/版本控制系统的实施方式。 https://github.com/collectiveidea/audited 您可以扩展它并将您的访问控制逻辑放在审计类验证中,因此它位于一个位置。 审计的gem还提供了一种巧妙的方法,通过使用观察器作为控制器上的过滤器来将当前用户传递到模型级别。 https://github.com/collectiveidea/audited/blob/master/lib/audited/sweeper.rb 但是还有其他方法https://github.com/bokmann/sentient_user经常被认为是hacky。

注意事项

  • 在任何一种情况下,你都必须防范模特的情况 在请求周期之外被操纵(在后台例程中, cronjob,console)当current_user定义不明确时。

  • 您通常不希望通过验证来处理访问冲突 错误但使用标准的http状态代码响应。

  • 第三,在Web应用程序设置中,您通常通过表单操作对象 通常您可以控制访问权来说出更新表单 实际上通常与更新本身具有相同的访问权限 (cancan甚至可以为new / create和edit / update提供常规别名) 后者通过验证来处理,这是一种通用的访问逻辑 会迷路。更不用说读取访问逻辑是不可能的 处理模型验证。

希望这会有所帮助