Rails版本升级后遭遇Psych::DisallowedClass错误的求助
看起来你在从Rails 4升级到Rails 5.2.8的过程中踩了YAML反序列化的安全限制坑,我来帮你梳理下问题根源和可行的解决办法:
问题核心
Rails 5.2开始收紧了YAML序列化的安全规则,默认不再允许反序列化自定义类(比如你的Policy模型)。而你尝试的config.active_record.yaml_column_permitted_classes配置是Rails 6.0才引入的,所以在5.2版本里调用这个方法会直接报错undefined method,这是你第二个问题的原因。
另外,你修改YAML.load_file时添加的permitted_classes可能没触碰到真正的错误触发点——因为报错是在创建EnsResponse对象时出现的,大概率是response_attributes这个字段里存储了序列化后的Policy对象,当ActiveRecord自动反序列化这个字段时,没有允许加载Policy类。
针对性解决办法
1. 移除无效的配置项
先把application.rb里那段yaml_column_permitted_classes的代码删掉,这个配置在Rails 5.2里根本不存在,留着只会报错。
2. 针对ActiveRecord字段配置允许的类
如果是response_attributes这个字段存储了包含Policy的YAML数据,你可以在EnsResponse模型里给这个字段的序列化逻辑单独配置允许的类:
class EnsResponse < ApplicationRecord # 给response_attributes字段指定序列化规则,允许需要的类 serialize :response_attributes, YAML do |c| c.permitted_classes = [Policy, Symbol, ActiveSupport::HashWithIndifferentAccess, ActionController::Parameters] end end
这种方式比全局配置更安全,只会开放特定字段的反序列化权限。
3. 全局添加白名单(不推荐但应急可用)
如果你有多个字段都涉及到Policy类的反序列化,也可以全局配置Psych允许加载这个类,在config/initializers/yaml.rb文件里添加:
# 全局允许Policy类的YAML反序列化 Psych::ClassLoader.add_whitelist(Policy)
不过要注意,全局白名单会降低安全性,尽量只添加确实需要的类。
4. 检查手动YAML加载的地方
如果你修改的mcp_services.yml加载逻辑确实也需要Policy类,那之前的配置是对的,但要确保这个文件里确实包含了Policy的序列化数据,并且加载逻辑是生效的。不过从报错栈来看,这个应该不是当前问题的触发点。
额外提醒
你可以先确认下@response.attributes里是否真的包含了Policy对象的序列化内容——Rails 4的时候默认允许序列化任意类,升级后这个行为被限制了,所以才会出现这个错误。
备注:内容来源于stack exchange,提问作者angelov_mm

