Rails中获取关联Trip下指定position的Stop经纬度报错如何解决?
解决Stop模型中获取下一个位置记录地理坐标的问题
嘿,我来帮你搞定这个报错问题~
你遇到的错误undefined method 'latitude' for #Stop::ActiveRecord_AssociationRelation:0x00007fbab4e15cf0,本质原因是:stop.trip.stops.where(position: 2)返回的是一个ActiveRecord集合对象(相当于一组Stop记录的容器),而不是单个Stop实例。集合对象本身没有latitude属性,只有单个Stop实例才有,所以直接调用就会报错。
下面给你几个可行的解决方案:
方案1:用find_by获取单个下一站记录
find_by方法会返回匹配条件的第一个单个记录(如果存在的话),完美替代你的where写法:
# 获取当前stop的下一个position的记录 next_stop = stop.trip.stops.find_by(position: stop.position + 1) # 一定要先判断next_stop是否存在,避免最后一个stop时出现nil调用错误 if next_stop Geocoder::Calculations.distance_between( [stop.latitude, stop.longitude], [next_stop.latitude, next_stop.longitude] ) end
方案2:在where后追加.first提取单个记录
如果你习惯用where,也可以在末尾加.first来从集合中取出第一个匹配的实例:
next_stop = stop.trip.stops.where(position: stop.position + 1).first # 同样需要判断next_stop是否存在再计算距离
方案3:利用acts_as_list内置的next_item方法(最优雅)
既然你已经用了acts_as_list gem,它本身就提供了获取下一个位置记录的方法next_item,完全不用手动处理position数值:
next_stop = stop.next_item if next_stop Geocoder::Calculations.distance_between( [stop.latitude, stop.longitude], [next_stop.latitude, next_stop.longitude] ) end
这个方法会自动基于当前stop的position,在同一个trip范围内找到下一个位置的记录,既简洁又符合gem的设计逻辑。
注意事项
无论用哪种方案,都要记得判断next_stop是否为nil——如果当前stop是trip中的最后一个,就没有下一站了,直接调用latitude会触发新的报错哦。
内容的提问来源于stack exchange,提问作者Jeremy Bray
相关产品推荐
相关产品推荐

