使用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
相关产品推荐
相关产品推荐

