FactoryBot创建的Mcc实例调用id_desc报nil转字符串错误如何修复
问题原因
错误的核心触发原因是String#upcase!方法的特性:该方法属于 Bang 方法,当调用的字符串本身已经是全大写格式时,不会修改原对象,直接返回nil。你的场景中刚好命中了这个逻辑:
- Mcc工厂默认配置的
descricao值为'MCC TESTE',本身已经是全大写格式 - 实例创建时触发
before_save回调执行params_to_uppercase方法的descricao.upcase!,此时因为字符串已经是全大写,返回nil,但回调未使用返回值所以没有报错 - 后续调用
id_desc方法时,再次执行descricao.upcase!,同样返回nil,字符串拼接操作尝试将nil转为String时触发类型错误
修复方案
1. 修复id_desc方法
将Bang版的upcase!替换为普通版upcase,普通版无论原字符串是否为全大写,都会返回大写后的新字符串,不会返回nil。同时推荐使用字符串插值替代<<拼接,写法更简洁也避免隐式类型转换问题:
def id_desc "#{codigo} - #{descricao.upcase}" end
2. 优化before_save回调(可选,规避潜在风险)
现有回调写法在descricao为nil时会抛出NoMethodError,优化后增加安全校验:
def params_to_uppercase self.descricao = descricao&.upcase end
3. 优化Mcc工厂(可选,规避主键冲突风险)
工厂中手动维护主键自增的逻辑没有必要,数据库和FactoryBot会自动处理主键生成,在事务回滚、并行测试的场景下手动写的自增逻辑容易出现主键冲突,直接删除工厂中的id配置行即可。
内容的提问来源于stack exchange,提问作者Andrea Elias
相关产品推荐
相关产品推荐

