You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails+Pundit环境下如何在Policy的Scope中检查类?

在Pundit的Scope中检查STI类的正确做法

完全可以在Policy的Scope中检查类,你的问题主要出在STI字段使用错误和常量引用问题上。

错误原因分析

  1. Rails单表继承(STI)默认用type字段存储子类名称,而非你代码里的class字段,这是Active Record的内置约定。
  2. 直接写Tropical会导致Policy无法正确解析该常量——要么是Rails自动加载时机未覆盖到,要么是常量作用域的问题。

解决步骤

1. 确认STI字段配置

  • 遵循Rails默认约定:确保fruits表包含type字符串字段(建议长度设为255)。
  • 若要自定义为class字段:在Fruit模型中添加配置:
# app/models/fruit.rb
class Fruit < ApplicationRecord
  self.inheritance_column = 'class' # 指定自定义STI字段名
end

2. 修正Policy中的查询代码

有两种可靠写法:

写法一:直接使用类名字符串(最稳妥,避免常量加载问题)
class FruitPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      if user.is_near_equator
        scope.where(type: "Tropical") # 字段名按你的STI配置选type或class
      else
        scope.where(type: "Temperate")
      end
    end
  end
end
写法二:通过类名.name获取字符串(更灵活,避免硬编码)
class FruitPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      if user.is_near_equator
        scope.where(type: Tropical.name)
      else
        scope.where(type: Temperate.name)
      end
    end
  end
end

如果仍出现常量未初始化错误,可在Policy顶部手动加载子类:

require 'tropical'
require 'temperate'

class FruitPolicy < ApplicationPolicy
  # ... 后续代码 ...
end

内容的提问来源于stack exchange,提问作者nakakapagpabagabag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:36:24