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

使用validates_each实现自定义验证时多属性规则获取异常求助

问题分析与解决方法

嘿,我一眼就瞅出问题所在啦!你的all_funders方法里的类变量缓存逻辑写错了,导致不管验证哪个属性,都只会返回第一次调用时的规则数组。

问题根源

你看这段代码:

def self.all_funders(attribute)
  @all_rules ||= parse_rules[attribute.to_sym][:options]
end

@all_rules是类实例变量,第一次调用这个方法时(比如验证:gender),它会被赋值为parse_rules[:gender][:options]也就是["Male", "Female"]。之后再验证:title的时候,因为@all_rules已经有值了,||=就不会再执行右边的代码,所以不管传什么attribute,返回的都是gender的规则数组,这就导致title永远验证失败啦!

修复方案

我们需要缓存整个规则哈希,而不是单个属性的选项。每次调用all_funders时,从缓存的完整规则里根据attribute取对应的选项就行。

修正后的代码如下:

class Rule
  include ActiveModel::Validations
  attr_accessor :gender, :title

  def self.parse_rules
    JSON.parse(File.read("rules.json"))
  end

  def self.all_funders(attribute)
    # 先缓存整个规则哈希,而不是单个属性的选项
    @all_rules ||= parse_rules
    # 根据传入的attribute获取对应的选项数组
    @all_rules[attribute.to_sym][:options]
  end

  validates_each :gender, :title do |record, attr, value|
    record.errors.add(attr, "Error message") if !all_funders(attr).include?(value)
  end
end

验证一下

假设你的rules.json内容是这样的:

{
  "gender": {
    "options": ["Male", "Female"]
  },
  "title": {
    "options": ["Mr", "Mrs"]
  }
}

现在验证:gender时会用["Male", "Female"],验证:title时会用["Mr", "Mrs"],就能正常工作啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:42:40