grape-entity >=0.5.0继承重写方法调用顺序异常问题
grape-entity 子类重写方法执行顺序异常问题
问题复现代码
module API module V1 module Entities class A < Grape::Entity expose :k expose :l expose :status def status 'HI' end end end end end module API module V101 module Entities class A < V1::Entities::A expose :status def status 'BYE' end end end end end
问题描述
使用grape-entity时出现不符合预期的执行逻辑:调用V101版本的A实体时,框架会先执行V1版本父类中定义的status方法,再执行V101子类重写的status方法,违背了子类重写方法优先调用的常规面向对象逻辑。
上述代码在grape-entity 0.4.8版本中运行正常:调用V101版本实体时仅会执行子类重写的status方法,升级到0.5.0及以上版本后执行逻辑发生变化。
相关环境配置
rails: 5.2 grape: 1.6.2
根因分析
该问题不属于使用疏漏,是grape-entity版本迭代带来的默认行为变更:
- 0.4.8及更早版本中,子类调用
expose声明和父类同名的字段时,会默认覆盖父类的同名字段暴露配置,因此只会执行子类的字段逻辑 - 0.5.0及之后版本调整了继承逻辑,子类重复
expose同名字段时不会覆盖父类配置,而是会在暴露列表中追加一条新的同名字段配置,框架会按父类到子类的注册顺序依次执行对应逻辑,最终返回最后一次执行的结果
修复方案
根据实际场景选择对应处理方式即可:
- 仅需要重写字段返回值逻辑时,直接删除子类中重复的
expose :status声明,仅保留重写的status方法,父类注册的字段配置会自动调用子类重写后的方法 - 需要同时调整字段的暴露参数(比如暴露条件、格式化规则、嵌套属性等)时,在
expose语句中添加override: true参数,显式声明覆盖父类的同名字段配置,示例代码如下:
module API module V101 module Entities class A < V1::Entities::A # 显式声明覆盖父类配置 expose :status, override: true def status 'BYE' end end end end end
内容的提问来源于stack exchange,提问作者Syed Hassan
相关产品推荐
相关产品推荐

