Rails中动态Concern在控制器继承场景下重复加载问题
解决Rails控制器继承场景下动态Concern重复引入无效问题
问题根源
ActiveSupport::Concern的included块只会在模块首次被包含的类上执行一次,子类继承父类后再次include同一模块时,Rails会跳过重复包含逻辑,导致子类无法触发对应自定义模块的加载。
解决方案
修改DynamicConcern模块,改用Ruby模块原生的append_features方法替代included块,确保每个类(无论父类还是子类)执行include DynamicConcern时都会触发动态加载逻辑:
module DynamicConcern def self.append_features(base) # 先执行模块包含的默认逻辑 super # 拼接并尝试加载对应自定义模块 concern_name = "Custom::#{ENV["CUSTOMER_NAME"].camelize}::#{base.name}Concern" if (concern_class = concern_name.safe_constantize) base.include(concern_class) end end end
说明
- 该修改无需改动现有任何模型或控制器代码,完全兼容原有架构。
append_features是Ruby模块的核心方法,每次调用include时都会触发,不受父类已包含模块的影响。- 保留了原有基于环境变量动态加载客户自定义模块的逻辑,同时解决了继承场景下的子类加载问题。
内容的提问来源于stack exchange,提问作者BvuRVKyUVlViVIc7
相关产品推荐
相关产品推荐

