如何将Rails模型中的逻辑迁移到service模块且不使用concern?
问题根因
你当前写法的问题出在模块内self.开头的方法属于模块本身的单例方法,不会通过include操作混入到目标类的类方法中,只有模块内直接定义的普通方法才会被混入为目标类的实例方法,所以你现在Account.first.test_code实际已经可以正常返回结果,仅Account.test_code_2会报方法不存在错误。
纯Ruby实现方案(无需使用Rails Concern)
以下两种方案都可以满足你的代码拆分需求,完全不依赖Rails的ActiveSupport::Concern能力:
方案1:使用Ruby原生included回调(无需修改Account原有引入代码)
修改app/services/some_service.rb代码如下:
module SomeService # 模块被include时自动触发的原生Ruby回调 def self.included(base) # 将ClassMethods子模块的方法扩展为目标类的类方法 base.extend ClassMethods end # 实例方法(混入后Account实例可直接调用) def test_code "abc" end # 存放类方法的子模块 module ClassMethods def test_code_2 "xyz" end end end
修改完成后原有的include SomeService代码无需调整,即可完全符合你的调用预期。
方案2:显式拆分实例方法和类方法引入
如果不想在模块内写回调逻辑,也可以直接修改app/models/account.rb的引入方式:
class Account < ApplicationRecord # 引入实例方法 include SomeService # 引入类方法 extend SomeService::ClassMethods end
对应some_service.rb保留实例方法和ClassMethods子模块即可,无需写self.included回调。
修改完成后重启Rails控制台即可验证效果:
Account.first.test_code返回"abc"Account.test_code_2返回"xyz"
内容的提问来源于stack exchange,提问作者CafeHey
相关产品推荐
相关产品推荐

