Rails7+ae_declarative_authorization:关联用户工作中心的委员会权限仅索引页生效问题
问题原因与解决方案
核心原因
你写的权限规则在索引页生效但单个资源页失效,本质是ae_declarative_authorization对集合资源和单个资源的属性检查逻辑差异:
- 索引页(集合查询)时,框架会把
work_center_ids => is_in {...}转换成SQL层面的关联过滤,自动匹配「委员会关联的工作中心与用户所属工作中心有交集」的场景,所以能正确返回符合条件的集合。 - 单个资源(如show/edit页)时,框架会直接检查当前
Council对象的work_center_ids数组是否作为一个整体存在于用户的工作中心ID集合中——这显然不成立,因为数组不可能是集合的单个元素,所以权限判断失败。
修复方案
方案1:调整属性匹配逻辑,改用关联交集判断
把规则改成通过关联模型的ID匹配,让框架对集合和单个资源都能正确解析:
has_permission_on :councils, :to => [:manage] do if_attribute :work_centers => { :id => is_in { user.employee.work_centers.ids } } end
这种写法会告诉框架:只要委员会关联的工作中心中,有任意一个ID在用户的工作中心ID集合里,就赋予权限。不管是集合查询还是单个资源检查,逻辑都会一致生效。
方案2:显式开启单个资源的属性检查
如果坚持原写法,需要确保控制器中对单个资源的权限检查开启attribute_check参数。比如在控制器里:
filter_access_to :show, :edit, :update, :destroy, :attribute_check => true
不过这种方式不如方案1可靠,因为原规则的逻辑本身就不适合单个资源的判断。
额外注意点
- 确认你的
Council模型中已经正确定义了与WorkCenter的关联:has_and_belongs_to_many :work_centers(因为用了create_joining_table)。 - 确保
user.employee不会返回nil,否则会触发报错,可加安全处理比如user.employee&.work_centers&.ids || []。
内容的提问来源于stack exchange,提问作者andresV
相关产品推荐
相关产品推荐

