Rails中如何基于模型独有属性有条件执行共享验证模块规则
实现方案
你之前的写法无法生效,因为included块内的proc没有被绑定到验证的条件触发逻辑,且验证方法是类层面调用的,套在实例判断逻辑中不会正常执行。
推荐直接利用Rails验证自带的条件参数实现,调整后的代码如下:
module SharedValidation extend ActiveSupport::Concern include ActiveModel::Validations included do # 所有共享验证统一绑定执行条件 validates_presence_of :name, :publisher, :author, if: :run_shared_validations? end private # 统一判断是否需要执行共享验证 def run_shared_validations? # 当前模型没有is_deleted字段时,默认执行验证 return true unless self.class.column_names.include?('is_deleted') # 有is_deleted字段时,仅未删除的记录执行验证 !is_deleted end end
方案优势
- 无侵入兼容原有模型:没有
is_deleted字段的Book类会正常执行所有共享验证,无需修改原有代码 - 自动适配特殊模型:带
is_deleted字段的Magazine类会自动触发判断,软删除的记录不会触发共享验证 - 扩展性强:如果后续有其他模型需要自定义验证触发条件,直接在对应模型中重写
run_shared_validations?方法即可,示例:
class Newspaper < ApplicationRecord include SharedValidation private # 自定义该模型的验证触发条件:仅已发布的报纸执行共享验证 def run_shared_validations? status == 'published' end end
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

