我正在将代码从构建在非标准自定义 PHP 框架中的应用程序转移到 Ruby on Rails(版本 3)中。在 PHP 版本中,所有 Controller 都非常胖,模型很瘦,我一直不同意,所以我很喜欢 Rails 在模型级别进行验证的方式,这可能是这些胖 Controller 中发生的事情的 90%目前。
我面临的一个问题,但不确定如何解决,是基于谁对模型进行更改而不同的验证规则。例如,管理员或记录的原始创建者应该能够执行诸如将记录标记为已删除(软删除)之类的操作,而其他人则不应该这样做。
class Something < ActiveRecord::Base
...
validates :deleted, :owned_by_active_user => true
...
end
class OwnedByActiveUserValidator < ActiveModel::EachValidator
validate_each(record, attr_name, attr_value)
# Bad idea to have the model know about things such as sessions?
unless active_user.admin? || active_user.own?(record)
record.errors.add :base, "You do not have permission to delete this record"
end
end
end
由于模型本身(理论上)不知道进行更改的用户,那么做这种事情的“rails 方式”是什么?我应该将事件用户设置为记录上的虚拟属性(实际上并未保存到 DB),还是应该只在 Controller 中执行这些检查?我不得不承认,让事件用户的模型检查权限确实感觉很奇怪,并且在测试模型时增加了复杂性。
我热衷于在模型中保留尽可能多的内容的一个原因是,我想同时提供 API(通过 OAuth 访问)和网站,而无需复制太多代码,例如这些类型的权限检查.
最佳答案
处理授权或将授权委托(delegate)给授权层实际上是 Controller 的工作。模型不应该知道也不必关心当前登录的人以及他/她的权限是什么——这是 Controller 的工作,或者 Controller 委派给的任何身份验证助手层。
你应该做:deleted
在- attr_accessible
通过 new
进行批量分配, create
, 或 update_attributes
. Controller 应单独检查认证用户的授权并调用deleted=
单独,如果经过身份验证的用户被授权。
有几个授权库和框架可以帮助授权或充当授权层,例如 cancan .
关于ruby-on-rails - 基于用户权限的 Rails 3 ActiveRecord 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3956632/