我的Rails应用程序有许多形成层次结构的模型.例如:零售商>部门>产品类别>产品>审核.
业务要求是高权限用户可以与新的或现有的"普通"用户"共享"层次结构中的任何单个元素.如果没有与它们共享对象,普通用户无权查看(或执行任何其他操作)层次结构的任何级别中的任何对象.
共享过程包括选择共享是否授予对目标对象的只读,读取更新或完整CRUD的权限.
共享任何对象将授予该对象和层次结构中所有较低级别对象的R/O,R/W或CRUD权限,以及对该对象的所有直接祖先的R/O权限.对象集合有机增长,因此权限系统只需记录user_id,共享的object_id和共享的性质(R/O,CRUD等)即可.由于此层次结构中的对象总体一直在增长,因此在DB中为每个用户/对象组合创建显式权限记录是不切实际的.
相反,在用户请求周期开始时,ApplicationController收集所有权限记录(用户X对部门#5具有CRUD权限)并将其保存在内存中的哈希中.权限模型知道如何在传递任何对象时评估哈希值 - Permission.allow?(:show,Department#5)将返回true或false,具体取决于用户权限哈希的内容.
我们来看,例如,部门模型:
# app/models/department.rb
class Department < ActiveRecord::Base
after_initialize :check_permission
private
def check_permission
# some code that returns true or false
end
end
Run Code Online (Sandbox Code Playgroud)
当check_permission方法返回true时,我想Department.first恢复数据库中的第一条记录,但是,如果check_permission返回false,我想返回nil.
现在,我有一个解决方案,默认范围触发权限检查,但这导致查询数量的2倍,对于具有大量对象的类,内存问题和时间/性能问题肯定会出现.
我的目标是使用after_initialize回调来预先允许对象.
然而,似乎after_initialize无法阻止原始对象被返回.它允许我重置对象属性的值,但不能免除它.
有谁知道如何实现这一目标?
编辑:
非常感谢到目前为止提供的所有答案和评论; 希望这个问题的扩展版本能够澄清事情.