You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建Question时保留自身验证并跳过Mappable模块的验证?

问题:创建Question实例时跳过Mappable模块验证,保留自身验证规则

我现有如下Question类:

class Question < ApplicationRecord
  include Mappable

  # 其他代码...

end

需求是创建Question实例时,保留Question自身的所有验证规则,但跳过来自Mappable模块的验证规则。目前我用question.save(validate: false)可以跳过所有验证,但希望改成类似question.save(mappable_validate: false)的方式,只跳过Mappable模块的验证。


补充:Mappable模块代码

module Mappable
  extend ActiveSupport::Concern

  included do
    attr_accessor :skip_map

    has_one :map_location, dependent: :destroy
    accepts_nested_attributes_for :map_location, allow_destroy: true, reject_if: :all_blank

    validate :map_must_be_valid, on: :create, if: :feature_maps?

    def map_must_be_valid
      return true if skip_map?

      unless map_location.try(:available?)
        skip_map_error = "Map error"
        errors.add(:skip_map, skip_map_error)
      end
    end

    def feature_maps?
      Setting["feature.map"].present?
    end

    def skip_map?
      skip_map == "1"
    end

  end
end

解决方案

方法1:利用现有skip_map属性快速实现

Mappable模块已经内置了skip_map属性和skip_map?方法,直接设置该属性就能跳过验证:

question = Question.new(...)
question.skip_map = "1" # 触发skip_map?返回true,跳过map_must_be_valid验证
question.save

这种方式不需要修改模块代码,直接用现有逻辑就能满足需求,同时保留Question自身的所有验证。

方法2:扩展save方法支持mappable_validate参数

如果想要更贴合你期望的save(mappable_validate: false)写法,可以修改Mappable模块,添加对自定义参数的支持:

module Mappable
  extend ActiveSupport::Concern

  included do
    attr_accessor :skip_map
    attr_accessor :skip_mappable_validation # 新增属性标记是否跳过验证

    has_one :map_location, dependent: :destroy
    accepts_nested_attributes_for :map_location, allow_destroy: true, reject_if: :all_blank

    # 修改验证触发条件,新增对skip_mappable_validation的判断
    validate :map_must_be_valid, on: :create, if: -> { feature_maps? && !skip_mappable_validation }

    def map_must_be_valid
      return true if skip_map?

      unless map_location.try(:available?)
        skip_map_error = "Map error"
        errors.add(:skip_map, skip_map_error)
      end
    end

    def feature_maps?
      Setting["feature.map"].present?
    end

    def skip_map?
      skip_map == "1"
    end

    # 重写save方法,处理自定义参数
    def save(options = {})
      if options[:mappable_validate] == false
        self.skip_mappable_validation = true
        # 移除自定义参数后调用父类save方法
        result = super(options.except(:mappable_validate))
        self.skip_mappable_validation = nil # 重置标记
        result
      else
        super(options)
      end
    end

  end
end

修改后就可以直接用你想要的方式调用:

question.save(mappable_validate: false)

这种方式更直观,也不会影响原有skip_map的功能。


内容的提问来源于stack exchange,提问作者CUB5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:40:11