Rails 3.1升级后找不到lib目录下定义的acts_as_userstamp方法如何解决
问题原因分析
- 自动加载路径配置不匹配
你当前配置的自动加载路径是项目根目录下的lib文件夹,但model_modifications.rb存放在app/lib目录下,#{config.root}/lib指向的是项目根目录/lib,并非目标路径,Rails无法扫描到app/lib下的文件。 - 不符合Rails自动加载触发规则
Rails的自动加载是懒加载机制,只有当代码中用到对应驼峰命名的常量时,才会去加载路径下匹配下划线命名的文件。你的model_modifications.rb没有定义对应的ModelModifications顶级常量,本质是给核心类打补丁的文件,永远不会触发自动加载的匹配规则,就算路径配置正确也不会被主动加载。 - 加载时机不符合要求
acts_as_userstamp是User模型定义阶段就会调用的类方法,补丁文件必须在User模型加载前完成加载,否则方法调用时补丁还未生效,一样会抛出未定义错误。
解决方案
- 首先修正自动加载路径,把
app/lib加入加载列表,修改application.rb中的对应配置:
config.autoload_paths += %W(#{config.root}/app/lib #{config.root}/lib) config.autoload_paths += Dir["#{config.root}/app/lib/**/", "#{config.root}/lib/**/"]
- 新增初始化文件强制提前加载补丁:在
config/initializers目录下创建load_model_patches.rb,写入如下内容,保证Rails启动阶段就加载补丁,优先级早于模型加载:
require 'model_modifications'
验证文件加载状态的方法
- 启动Rails Console执行命令:
$LOADED_FEATURES.grep /model_modifications/,如果返回结果包含文件的完整绝对路径,说明文件已经被加载,反之则未加载。 - 确认文件加载后执行命令:
ActiveRecord::Base.respond_to?(:acts_as_userstamp),返回true说明方法已经正确注入到ActiveRecord::Base上。 - 若以上两项检查都通过仍报错,排查是否有其他初始化逻辑、中间件在补丁加载前就提前触发了
User模型的加载。
内容的提问来源于stack exchange,提问作者thefonso
相关产品推荐
相关产品推荐

