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

Ruby3.1.2+Rails6.1.7调用discard gem报Psych错误求助

修复Ruby 3.1.2 + Rails 6.1.7中调用discard#discard时的Psych::DisallowedClass异常

可能原因

  • Rails 6.1.7在Ruby 3.1环境下,YAML序列化/反序列化的权限配置存在局部覆盖问题,discard gem处理记录时触发了未授权类的反序列化,全局配置未覆盖该场景。
  • discard gem内部操作可能绕过ActiveRecord的YAML配置,直接调用了Psych底层方法。

解决方案尝试

1. 确保配置正确生效(取消注释并重启应用)

你之前的配置处于注释状态,先取消注释并重启应用(即使无Spring也需重启服务器):

# config/application.rb
config.active_record.yaml_column_permitted_classes = [Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess, ActiveSupport::TimeWithZone, Time]
config.active_record.use_yaml_unsafe_load = false # 优先保持安全,非必要不开启unsafe模式
config.active_support.use_yaml_unsafe_load = false

额外添加ActiveSupport的YAML允许类配置(针对非ActiveRecord列的序列化场景):

config.active_support.permitted_yaml_classes = [ActiveSupport::TimeWithZone, Time, Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess]

2. 针对discard操作的局部兼容处理

若全局配置不生效,可在调用discard的代码块中临时授权类:

# 临时添加允许类,操作后恢复
original_permitted = Psych::ClassLoader::PermittedClasses.dup
Psych::ClassLoader::PermittedClasses.add(ActiveSupport::TimeWithZone)
object.discard
Psych::ClassLoader::PermittedClasses.replace(original_permitted)

或使用unsafe模式临时包裹(仅建议在可信场景下使用):

Psych.unsafe_load do
  object.discard
end

3. 升级discard gem到最新版本

检查discard gem是否有Ruby 3.1/Rails 6.1.7的兼容修复,执行更新命令:

bundle update discard

4. 初始化脚本补全配置(针对缓存序列化场景)

若discard依赖缓存机制触发异常,添加初始化脚本覆盖缓存的YAML解析逻辑:

# config/initializers/psych_permit_classes.rb
Rails.application.config.after_initialize do
  ActiveSupport::Cache::Store.send(:define_method, :load) do |data|
    if data.is_a?(String) && data.start_with?("---")
      YAML.load(data, permitted_classes: [ActiveSupport::TimeWithZone, Time, Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess])
    else
      super(data)
    end
  end
end

验证步骤

每次修改配置或代码后,重启应用并测试object.discard操作,确认异常是否消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:55:20