ROR服务端DataTable重置过滤器报nil:NilClass的+方法错误,修改方案是否合理?
问题解答
报错原因
你遇到的undefined method '+' for nil:NilClass报错,根本原因是重置过滤器后,部分roster关联的training_sets为空,或是第一条training_set的title字段为nil。此时安全调用符&.会返回nil,nil执行和字符串的+拼接操作就会触发该异常。
修复方式合理性判断
你将+改为+=的修复方式不合理,属于巧合生效的临时修复,存在严重隐患:
+=本质是赋值运算符,该操作会直接修改roster.training_sets.first.title的原始值,如果后续业务逻辑还需要用到该字段的原生内容,会出现不可预期的数据污染问题- 当
roster.training_sets&.first&.title真的为nil时,nil += 字符串依然会抛出完全相同的报错,你当前没有报错只是测试场景下刚好不存在title为nil的情况,没有从根源解决问题。
正确修复方案
你只需要主动对可能为nil的title做兜底处理,保证拼接操作的左值一定是字符串即可,推荐两种写法:
- 调用
to_s做自动类型转换:
column << roster.training_sets&.first&.title.to_s + (roster.training_sets.size>1 ? '<br><a class="fa-sm" data-target="#trainingSet-'+roster.id.to_s+'" data-toggle="modal" href="#">See more</a><div aria-hidden="true" aria-labelledby="exampleModalLabelTrainingSet" class="modal fade bd-example-modal-lg" id="trainingSet-' + roster.id.to_s + '" role="dialog" tabindex="-1"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">विषयगत क्षेत्र</h5><button aria-label="Close" class="close" data-dismiss="modal" type="button"><span aria-hidden="true"> ×</span></button></div><div class="modal-body"><ul class="bg-light p-3" style="line-height: 30px;">' + (roster.training_sets.map {|t_set| t_set.title }).map(&:inspect).join('<br>') + '</ul></div></div></div></div>' : '')
- 显式给默认空值:
column << (roster.training_sets&.first&.title || '') + (roster.training_sets.size>1 ? '<br><a class="fa-sm" data-target="#trainingSet-'+roster.id.to_s+'" data-toggle="modal" href="#">See more</a><div aria-hidden="true" aria-labelledby="exampleModalLabelTrainingSet" class="modal fade bd-example-modal-lg" id="trainingSet-' + roster.id.to_s + '" role="dialog" tabindex="-1"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">विषयगत क्षेत्र</h5><button aria-label="Close" class="close" data-dismiss="modal" type="button"><span aria-hidden="true"> ×</span></button></div><div class="modal-body"><ul class="bg-light p-3" style="line-height: 30px;">' + (roster.training_sets.map {|t_set| t_set.title }).map(&:inspect).join('<br>') + '</ul></div></div></div></div>' : '')
内容的提问来源于stack exchange,提问作者Sanju Basnet
相关产品推荐
相关产品推荐

