Rails/ActiveRecord:非持久化对象关联查询验证的解决方案
解决方案:统一处理内存与数据库中的关联记录
问题核心在于find_by是ActiveRecord的数据库查询方法,只会查找已持久化到数据库的记录,而通过build创建的未保存实例仅存在于内存中,无法被SQL查询捕获。
最优的解决方式是先将关联集合转换为包含内存+数据库记录的数组,再用Ruby原生方法查找,既能覆盖生产环境的持久化场景,也能兼容测试环境的未持久化场景:
修改Child模型中的val_matches_sister_val方法:
def val_matches_sister_val matching_sister = parent.other_children.to_a.find { |oc| oc.name == search_name } val == matching_sister&.val end
原理说明
parent.other_children.to_a会先加载数据库中已存在的other_children记录(如果尚未加载),再合并内存中通过build创建的未保存实例,得到完整的关联集合数组。- Ruby的
find方法在数组中按条件查找,能匹配到内存中的未持久化对象,完美替代仅针对数据库的find_by。
这种方案无需区分对象是否持久化,代码简洁统一,既满足生产环境的验证需求,也能在RSpec测试中使用未持久化对象提升速度,比你提到的三种方案更优雅。
内容的提问来源于stack exchange,提问作者kid_drew
相关产品推荐
相关产品推荐

