2

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

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

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

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

4

2 回答 2

4

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

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

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

于 2012-06-12T22:35:57.370 回答
2

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

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

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

注意事项

  • 在任何一种情况下,当 current_user 定义不正确时,您都必须防止在请求周期之外(在后台例程、cronjob、控制台中)操作模型的情况。

  • 您通常不想使用验证错误来处理访问冲突,而是使用标准的 http 状态代码响应。

  • 第三,在网络应用程序设置中,您通常通过表单操作对象,并且通常您已经可以控制访问权限,例如更新表单,实际上通常与更新本身具有相同的访问权限(甚至可以具有新建/创建和编辑的通用别名/update) 因此,如果后者通过验证处理,则此通用访问逻辑将丢失。更不用说模型验证无法处理读取访问逻辑。

希望这可以帮助

于 2012-06-13T11:50:06.740 回答