自定义gem中扩展ActiveRecord提示类方法不存在该如何解决
问题原因
核心错误有两处:
Uber::Extensions模块中错误使用了instance_methods块,ActiveSupport::Concern没有提供该方法定义实例方法,实例方法直接写在模块顶层即可,错误写法会导致模块逻辑加载异常。ActiveSupport.on_load(:active_record)块中不需要重新打开ActiveRecord::Base类,该块的执行上下文本身就是ActiveRecord::Base,额外开类会引发加载顺序问题,导致扩展没有正确挂载。
另外补充:你预期的「实例化User时输出blah」存在逻辑偏差,enable_my_uber_features :blah是类定义阶段就会执行的类方法,不会等到实例化时才触发。
修复方案
步骤1:修正扩展模块写法
修改my_uber_gem/lib/uber/extensions.rb代码:
# my_uber_gem/lib/uber/extensions.rb require 'active_support/concern' module Uber module Extensions extend ActiveSupport::Concern # 实例方法直接写在模块内,不需要套任何块 def foo p :bar end class_methods do def enable_my_uber_features(value) # 如果需要实例化时输出,可在这里加初始化回调 # after_initialize { p value } p value end end end end
步骤2:修正扩展挂载逻辑
修改my_uber_gem/lib/uber_gem.rb代码:
# my_uber_gem/lib/uber_gem.rb require "active_support" require "active_record" # 补全active_record依赖加载 require "uber/extensions" ActiveSupport.on_load(:active_record) do # 直接在当前上下文include扩展,不需要重新打开ActiveRecord::Base include Uber::Extensions end
步骤3:验证gem加载
确保你的Rails项目Gemfile中正确引入了该gem,本地开发的gem需要指定path参数:
gem 'my_uber_gem', path: '本地gem的绝对/相对路径'
执行bundle install后重启Rails服务/控制台即可生效。
内容的提问来源于stack exchange,提问作者Nick M
相关产品推荐
相关产品推荐

